3
votes
// File test.cpp
#include <my_global.h>
#include <algorithm>
int main()
{
    return 0;
}

Compiled with: g++ -c -I /usr/local/mysql/include/mysql/ test.cpp, where /usr/local/mysql is the mysql install directory.Then the compiler report the following errors:

In file included from /usr/include/c++/4.4/algorithm:61, from test.cpp:3: /usr/include/c++/4.4/bits/stl_algobase.h:232:56: error: macro "min" passed 3 arguments, but takes just 2 /usr/include/c++/4.4/bits/stl_algobase.h:253:56: error: macro "max" passed 3 arguments, but takes just 2 In file included from /usr/include/c++/4.4/bits/stl_algo.h:61, from /usr/include/c++/4.4/algorithm:62, from test.cpp:3: /usr/include/c++/4.4/bits/algorithmfwd.h:353:41: error: macro "max" passed 3 arguments, but takes just 2 /usr/include/c++/4.4/bits/algorithmfwd.h:364:41: error: macro "min" passed 3 arguments, but takes just 2 In file included from /usr/include/c++/4.4/algorithm:61, from test.cpp:3: /usr/include/c++/4.4/bits/stl_algobase.h:186: error: expected unqualified-id before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:186: error: expected ‘)’ before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:186: error: expected ‘)’ before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:186: error: expected initializer before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:209: error: expected unqualified-id before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:209: error: expected ‘)’ before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:209: error: expected ‘)’ before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:209: error: expected initializer before ‘const’ /usr/include/c++/4.4/bits/stl_algobase.h:232: error: ‘std::min’ declared as an ‘inline’ variable /usr/include/c++/4.4/bits/stl_algobase.h:232: error: template declaration of ‘const _Tp& std::min’ /usr/include/c++/4.4/bits/stl_algobase.h:235: error: expected primary-expression before ‘if’ /usr/include/c++/4.4/bits/stl_algobase.h:235: error: expected ‘}’ before ‘if’ /usr/include/c++/4.4/bits/stl_algobase.h:237: error: expected unqualified-id before ‘return’ /usr/include/c++/4.4/bits/stl_algobase.h:253: error: ‘max’ declared as an ‘inline’ variable /usr/include/c++/4.4/bits/stl_algobase.h:253: error: template declaration of ‘const _Tp& max’ /usr/include/c++/4.4/bits/stl_algobase.h:256: error: expected primary-expression before ‘if’ /usr/include/c++/4.4/bits/stl_algobase.h:256: error: expected ‘}’ before ‘if’ /usr/include/c++/4.4/bits/stl_algobase.h:258: error: expected unqualified-id before ‘return’ /usr/include/c++/4.4/bits/stl_algobase.h:259: error: expected declaration before ‘}’ token

I think that there's some name conflict between my_global.h and algorithm, so I wrap my_global.h in a namespace:

// File test.cpp
namespace MYSQL_NAMESPACE {
    #include <my_global.h>
}
#include <algorithm>
int main()
{
    return 0;
}

But it doesn't help, the compiler still report the same errors. Then I change the include order as following:

// File test.cpp
#include <algorithm>
#include <my_global.h>
int main()
{
    return 0;
}

Every thing goes well now.

Does Anybody Really Know What The Problem It Is?

TKS!

3
What version of MySQL are you using?Mark Byers
You should usually include standard C headers, followed by standard C++ headers, followed by third party libraries in any case. (For the record, windows.h has this same problem -- you turn off definition of min and max using the macro NOMINMAX there)Billy ONeal
The MySQL version I'm using is 5.1.44, I know the problems now, Thank you!zJay
@Billy ONeal, Though it is a good habit, just changing the include order to "C headers" > "std headers" > "third libs" doesn't completely solve this problem. For example, file "util1.h" includes <algorithm> and file "util2.h" includes <my_global.h>, now "test.cpp" includes both "util1.h" and "util2.h", which are all third party libaries to "test.cpp", so the include order of third party libs also affects the compile result in this case. Turning off the definition of "min" and "max" may be the solution.zJay
Yep -- not always possible to take care of these things where macros are involved.Billy ONeal

3 Answers

7
votes

It seems that the mysql header defines a macro min.

#if !defined(max)
#define max(a, b)       ((a) > (b) ? (a) : (b))
#define min(a, b)       ((a) < (b) ? (a) : (b))
#endif

This has been reported to MySQL as bug 28184. The bug is marked as closed, so try updating to the newest version. According to the bug page it should be fixed in version 5.1.23, version 6.0.4 and newer versions.

3
votes

Apparently the namespace trick does not work because min/max are macros and the preprocessor does not look at namespace scope.

This might fix the problem:

#include <my_global.h>
#undef min
#undef max
#include <algorithm>

The whole thing looks horrible though :)

0
votes

It looks like my_global.h defines some name used by algorithm as a preprocessor macro, causing compilation to fail. With the ordering that works, you won't be able to use whatever it is that my_global.h clobbers, but your code will at least compile unless you need that feature. Since preprocessor macros are not namespaced, the namespace wrapping will not help, as you have observed.

Therefore, it sounds like my_global.h is broken, but if everything works just use the include order that works and go with it. That's my preferred include order anyway - standard library headers first, followed by external library headers, followed by internal headers.