1
votes

I have the following code:

#ifndef min
#define min(a,b) (((a)< (b)) ? (a) : (b))
#endif

int test(){
    return min(0,1);
}

Which works OK. However, if I include some header file (from a graph database, the content of this header file can be found here: http://www.sparsity-technologies.com/dex), the compiler complains that min is not defined, like Dex.h just cancelled the effect of my marco definition.

However, Dex.h doesn't contain any undefined statements. I couldn't move the macro definition, because it is actually included in another header file.

What's wrong and what should I do?

#ifndef min
#define min(a,b) (((a)< (b)) ? (a) : (b))
#endif

#include "gdb/Dex.h"

int test(){
    return min(0,1);
}

The compiler error I get is:

 test.c:9:16: error: 'min' was not declared in this scope
2
I'm kind of confused why you put the macro before the include anyway. And there are std::max and std::min. No need to make a macro with a conflicting name. - chris
well, did it? does Dex.h do anything to undefine min? - xaxxon
Well, run it through the precompiler and let's see what you end up with. - xaxxon
# 1862 "/usr/lib/gcc/x86_64-redhat-linux/4.5.1/../../../../include/c++/4.5.1/x86_64-redhat-linux/bits/c++config.h" <== that's your file.. but I have no idea why this exists, what it does, or why this other thing includes it. - xaxxon
Ugh, please, please make macros look like macros by naming them in all uppercase. Otherwise you're asking for trouble later when someone tries to use std::min, tries to name a variable min, or uses your min macro not expecting it to evaluate its arguments multiple times. (Conversely, things that aren't macros shouldn't be named in all uppercase, although many people have unfortunately perverted that to include non-macro constants.) - jamesdlin

2 Answers

2
votes

Presumably, that header file #undef-fed min (either directly, or via another header file that it included).

Here are three solutions (in increasing order of preference):

  1. Move your #define below your #include.
  2. Use a function/template instead of a macro.
  3. Use std::min, which can be found in the standard <algorithm> header.
3
votes

Looks like you're including c++config.h, which says:

00307 // This marks string literals in header files to be extracted for eventual
00308 // translation.  It is primarily used for messages in thrown exceptions; see
00309 // src/functexcept.cc.  We use __N because the more traditional _N is used
00310 // for something else under certain OSes (see BADNAMES).
00311 #define __N(msgid)     (msgid)
00312 
00313 // For example, <windows.h> is known to #define min and max as macros...
00314 #undef min
00315 #undef max

Looking further, it seems that's included by string which is included by

# 39 "dex/includes/dex/gdb/common.h" 2