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
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
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):
Move your #define below your #include.
Use a function/template instead of a macro.
Use std::min, which can be found in the standard <algorithm> header.
Related
Since preprocessor don't report an error when checking value of preprocessor's symbol that isn't actually defined (usually due to the lack of #include "some_header.h"), I use this cumbersome three line construction with "defined":
#if !defined(SOME_SYMBOL)
#error "some symbol isn't defined"
#endif
#if SOME_SYMBOL == 1
// Here is my conditionally compiled code
#endif
And the way with "#ifndef" is the same.
Is there a more elegant way to perform this check?
In your construction you could use an else block to skip the check for defined:
#if SOME_SYMBOL == 1
// Here is my conditionally compiled code
#else
// error
#endif
But in principle the comments are right. #if !defined and the shorthand #ifndef are the two available versions.
Currently, you are checking if SOME_SYMBOL is equals to 1. Do you execute different code based on that value ?
If not, you could simply use:
#ifdef SOME_SYMBOL
// Here is my conditionally compiled code
#else
// error
#endif
And now it's a short step to the typical c++ include guards. Copying from that wikipedia link, here is a grandparent.h file:
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
struct foo {
int member;
};
#endif /* GRANDPARENT_H */
Now, even if you end up including this header twice, it will only be executed once.
I wrote this simple program
#include <time.h>
int main()
{
#if ((clock_t)1000)
int x = 10;
#endif
return 0;
}
On compilation, I see the following error:
Error C1012 unmatched parenthesis: missing ')'
Why am I getting this error?
Changing the line from:
#if ((clock_t)1000)
to:
#if (clock_t)1000
resolves the compilation error.
But I can't do that, since ((clock_t)1000) is defined as a macro using the #define directive in the limits.h header file as :
#define CLOCKS_PER_SEC ((clock_t)1000)
and I need to use that directly.
EDIT:
Please pardon me for framing the question in such an unclear way.
Reframing my question now:
I have the following code:
#include <time.h>
#define DUMMY_CLOCKS_PER_SEC ((clock_t)1000)
int main()
{
#if CLOCKS_PER_SEC != DUMMY_CLOCKS_PER_SEC
#error "out of sync"
#endif
return 0;
}
But this gives the compilation error:
Error C1012 unmatched parenthesis: missing ')'
The preprocessor doesn't know anything about C++ datatypes, and doesn't understand cast expressions. It's used for simple text processing, and == and != can only compare single tokens.
Do the comparison in C++, not the preprocessor.
static_assert(CLOCKS_PER_SEC == DUMMY_CLOCKS_PER_SEC, "out of sync");
int main() {
return 0;
}
Don't worry about the runtime performance overhead. Since both macros expand to literals, the compiler will optimize it away.
You are confusing a preprocessor macro definition (CLOCKS_PER_SEC) with its expansion (that is implementation defined, and in your case seems to be ((clock_t)1000)).
It's not very clear what you want to do in your code.
If you want to check if this macro is defined, you can use the preprocessor #ifdef, e.g.:
#ifdef CLOCKS_PER_SEC
// your code
#endif
Anyway, this CLOCKS_PER_SEC macro is defined by the standard, so it should be always defined in a standard-compliant time.h library implementation.
If you have something different in your mind, please clarify your goal.
EDIT Based on your clarifying comment below, you may want to use an if to compare the values (expansions) of these two macros:
if (DUMMY_CLOCKS_PER_SEC != CLOCKS_PER_SEC) {
...
} else {
...
}
((clock_t)1000) is defined as a macro using the #define directive in the limits.h header file as :
#define CLOCKS_PER_SEC ((clock_t)1000)
The file does not define a macro named ((clock_t)1000). It defines a macro named CLOCKS_PER_SEC. ((clock_t)1000) is the value of the macro.
((clock_t)1000) is not a macro and is something that cannot be used in an #if directive.
Thanks for all the responses everyone.
Another solution I figured out for this problem is to use constexpr specifier which is a feature of c++11. ConstExpr allows us to evaluate the value of a variable or a function at compile time.
Changing the code from:
#if CLOCKS_PER_SEC != DUMMY_CLOCKS_PER_SEC
#error "out of sync"
#endif
to the following resolves the issue:
constexpr int DUMMY_CLOCK_NOT_EQUAL = (DUMMY_CLOCKS_PER_SEC != CLOCKS_PER_SEC) ? 1 : 0;
#if DUMMY_CLOCK_NOT_EQUAL
#error "out of sync"
#endif
In attempting to compile the SFML source code, I found an issue where std::min was suspiciously not recognised by the compiler, which gave the error of
error: expected unqualified-id before ‘(’ token
Despite being declared. Doing a manual trace I whittled the culprit file down to X11/Xlibint.h. Checking further I found these two hidden nasties declared:
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
Now I was always taught macros should either make use of starting underscores, all caps lock or a unique identifier to avoid precisely what has occurred here: a naming conflict. What I'm even more baffled by is why X11/Xlibint.h would make use of perhaps the absolutely most common terms min and max, especially in full knowledge that std::min and std::max, especially with using namespace std, become both min and max.
You can replicate the error in two ways, and depends on the order the header files are declared in. If X11/Xlibint.h is declared after algorithm, it overwrites the min/max definition, which you can see with the example code below:
#include <iostream>
#include <algorithm> //declares std::min std::max
#include <X11/Xlibint.h> //declares min / max macro, which seems to overwrite std:min / std::max
int main()
{
std::cout<<"Min is: "<<min(0,10)<<std::endl; //doesn't error
std::cout<<"Min is: "<<std::min(0,10)<<std::endl; //errors with unqualified id despite algorithm being declared
}
Which produces the errors:
main.cpp|8|error: expected unqualified-id before ‘(’ token|
For those of you who would simply suggest in such a simple project to declare the headers the other way around, it's not possible in large projects or libraries to 100% ensure the order is the right way around (I had to trace through 30+ files in SFML just to find the source of the conflict), especially if a number of files declare algorithm because the clobber occurs when algorithm is declared before X11/libint.h (and given algorithm is more commonly used than X11/libint.h it's more likely to occur in that order).
It can also occur the other way around, but it's more convoluted:
#include <X11/Xlibint.h>
//Only defined if X11 already defines it. We redefine it to demonstrate it's used instead of std::min
#ifdef min
#undef min
#define min(a,b) -10;
#endif
int N = min(0,10); //Defined as a macro, implicitly
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int I = min(0,20); //No longer the macro, implicitly
std::cout<<"N is: "<<N<<" I is: "<<I<<std::endl; //N is -10, I is 0
return 0;
}
I cannot be the only one thinking that the declaration in X11/Xlibint.h of min/max was a poor choice of naming convention?
My proposal for fixing it would be to either:
Rename the macros (for example _MIN or _MAX), and/or
Undefining them prior to the header leaving scope.
I'm trying to use Unity Builds to shorten the build time of a c++ project on Windows. One of several problems I met is the single file scope issue.
Once all source codes are included in a single source file, they all share the same file scope. All locally defined symbols using same name will be duplicate and causing compile errors.
Currently, I have to change each duplicated names with a file postfix to avoid duplication. But I think there might be better solutions.
I'd like to share my current solution.
In generation of unity_build_source_<index>.cpp files, define a UNITY_BUILD macro and wrap each include source code with macros:
// unity_build_souce file, automatically generated, do not edit manually.
#define UNITYBUILD_CONCATENATE_DETAIL(x, y) x##y
#define UNITYBUILD_CONCATENATE(x, y) UNITYBUILD_CONCATENATE_DETAIL(x, y)
#define UNITYBUILD_MAKE_UNIQUE(x) UNITYBUILD_CONCATENATE(x, _UNITYBUILD_COUNTER)
#define UNITY_BUILD
// for each source code
#define _UNITY_BUILD_COUNTER 1
#include <path/to/source1.cpp>
#undef _UNITY_BUILD_COUNTER
#define _UNITY_BUILD_COUNTER 2
#include <path/to/source2.cpp>
#undef _UNITY_BUILD_COUNTER
// ...
In source codes, use UNITYBUILD_MAKE_UNIQUE macro for names that is duplicated.
#ifdef UNITY_BUILD
#define a_duplicated_variable UNITYBUILD_MAKE_UNIQUE(a_duplicated_variable)
#define ADuplicatedClass UNITYBUILD_MAKE_UNIQUE(ADuplicatedClass)
#define aDuplicatedFunction UNITYBUILD_MAKE_UNIQUE(aDuplicatedFunction)
#endif
namespace
{
int a_duplicated_variable = 3;
class ADuplicatedClass
{
public:
ADuplicatedClass(int ){}
};
}
void aDuplicatedFunction()
{
ADuplicatedClass c(a_duplicated_variable);
}
#ifdef UNITY_BUILD
#undef a_duplicated_variable
#undef ADuplicatedClass
#undef aDuplicatedFunction
#endif
I know this solution is still bad looking. Compared with manually change each duplicated symbols, it keeps the old names the look as they were.
For some reason I need to temporarily disable some macros in a header file and the #undef MACRONAME will make the code compile but it will undef the existing macro.
Is there a way of just disabling it?
I should mention that you do not really know the values of the macros and that I'm looking for a cross compiler solution (should work at least in GCC and MSVC).
In MSVC you could use push_macro pragma, GCC supports it for compatibility with Microsoft Windows compilers.
#pragma push_macro("MACRONAME")
#undef MACRONAME
// some actions
#pragma pop_macro("MACRONAME")
Using just the facilities defined by Standard C (C89, C99 or C11), the only 'disable' mechanism is #undef.
The problem is there is no 're-enable' mechanism.
As others have pointed out, if the header file containing the macro definitions is structured so that it does not contain any typedef or enum declarations (these cannot be repeated; function and variable declarations can be repeated), then you could #undef the macro, do what you need without the macro in effect, and then re-include the header, possibly after undefining its protection against reinclusion.
If the macros are not defined in a header, of course, you are stuck until you refactor the code so that they are in a header.
One other trick is available - if the macros are function-like macros and not object-like macros.
#define nonsense(a, b) b /\= a
int (nonsense)(int a, int b)
{
return (a > b) ? a : b;
}
The function nonsense() is defined fine, despite the macro immediately before it. This is because a macro invocation - for a function-like macro - must be immediately followed by an open parenthesis (give or take white space, possibly including comments). In the function definition line, the token after 'nonsense' is a close parenthesis, so it is not an invocation of the nonsense macro.
Had the macro been an argument-less object-like macro, the trick would not work:
#define nonsense min
int (nonsense)(int a, int b)
{
// Think about it - what is the function really called?
return (a > b) ? a : b;
}
This code defines a bogus function that's called min and is nonsensical. And there's no protection from the macro.
This is one of the reasons why the standard is careful to define which namespaces are reserved for 'The Implementation'. The Implementation is allowed to define macros for any purpose it desires or needs, of any type (function-like or object-like) it desires or needs, provided those names are reserved to the implementation. If you as a consumer of the services of The Implementation try to use or define a name reserved to the implementation, you must be aware that your code will probably break sooner or later, and that it will be your fault, not the fault of The Implementation.
Macros make my knees go weak, but wouldn't the most universal solution be to restructure your code so that you wouldn't need to reenable the macro again in the same source file? Wouldn't it be possible to extract some code into a separate function and a separate source file where you can undef the offending macro.
The macros come from some header file, so you should have access to their values. You can then do something like
#include <foo.h> // declares macro FOO
// Do things with FOO
#undef FOO
// do things without FOO
#include <foo.h> // reenable FOO
Your header should then be designed along these lines
#ifndef FOO
#define FOO do_something(x,y)
#endif
EDIT:
You may think that it's that easy:
#ifdef macro
#define DISABLED_macro macro
#undef macro
#endif
// do what you want with macro
#ifdef DISABLED_macro
#define macro DISABLED_macro
#endif
But it's not (like the following example demonstrates)!
#include <iostream>
#include <limits>
#include <windows.h>
#ifdef max
#define DISABLED_max max
#undef max
#endif
int main()
{
std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
#ifdef DISABLED_max
#define max DISABLED_max
#endif
std::cout << max(15,3) << std::endl; // error C3861: "max": identifier not found
return 0;
}
Using #undef on the macro and re-including the original header is also not likely to work, because of the header guards.
So what's left is using the push_macro/pop_macro #pragma directives.
#pragma push_macro("MACRO")
#undef MACRO
// do what you want
#pragma pop_macro("MACRO")
There are specific rules for function-like macroses invokation in C/C++ language.
The function-like macroses have to be invoked in the following way:
Macros-name
Left parethesis
One token for each argument separated by commas
Each token in this list can be separared from another by whitespaces (i.e. actual whitespaces and commas)
With one trick you "disable preprocessor mechanism" with breaking rules for function-like macro invokation, but be still within a rules of function calling mechanism...
#include <iostream>
using namespace std;
inline const char* WHAT(){return "Hello from function";}
#define WHAT() "Hello from macro"
int main()
{
cout << (*WHAT)() << "\n"; // use function
cout << (WHAT)() << "\n"; // use function
cout << WHAT () << "\n"; // use macro
return 0;
}