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
Related
Is there a way to define a constexpr before an #if compiler directive as its input?
In other words, can #if have inputs from constexpr? If not, does it mean #if directive is evaluated before the constexpr?
constexpr int enable_debug = true;
#if (enable_debug)
std::string debug_logs;
#endif
for(int i=0;i<10;i++) {
f(i);
#if (enable_debug)
debug_logs += std::to_string(i);
#endif
}
#if (enable_debug)
std::court << debug_logs;
#endif
This question has two objectives:
Is "directive time" or "pragma time" earlier than compile time?
I want to build some code only conditionally, but the code defined a variable, so I cannot use if constexpr().
No, there is no way to do this. Preprocessor commands are applied in an earlier phase of translation than the evaluation (or even full parsing) of variable definitions. #if can do normal integer arithmetic and comparisons, and can expand preprocessor macros which were created with #define, but it cannot inspect non-preprocessor code.
You'll either need to make enable_debug a preprocessor macro, or change from preprocessor conditionals to if or if constexpr (which, of course, have their own limitations).
In C and C++, when using a macro like so:
#if ( 1 == __MY_MACRO__ )
// Some code
#endif
The compiler will not catch if MY_MACRO is not defined and will consider it 0. This could cause a lot of hidden bugs when the design of the code is intended such that the macro must be defined (non-zero).
Is there away to get to compiler to report this, even if the compiler natively doesn't look for such thing?
Use #if defined(__MY_MACRO__) to test if the macro value is defined.
#ifndef __MY_MACRO__
#error "MY_MACRO NOT DEFINED"
#endif
You can use #ifdef or ifndef to check if a macro is defined of not.
Example :
#ifndef MY_MACRO
# error "MY_MACRO is not defined"
#endif
More informations can be found here : https://gcc.gnu.org/onlinedocs/cpp/Ifdef.html
I have to resort to
#if !defined( __MY_MACRO__ )
MACRO_NOT_DEFINED; //to cause compiler error
#endif
#if ( 1 == __MY_MACRO__ )
//code
#endif
Which looks rather ugly.
Someone I know came up with a clever 1 liner
#if ( (1/defined(_MY_MACRO__) && 1 == _MY_MACRO__ ) )
//code
#endif
If _MY_MACRO__ is not defined, it will cause divide by zero error.
If the macro is used as compile switch try this way.
in a configuration file:
#define FEATURE_1_ENABLED() (1)
#define FEATURE_2_ENABLED() (0)
in place you checking the value:
#if FEATURE_1_ENABLED()
// whatever
#endif
in contrast to your example this does show error when macro is not visible by mistake (at least in my ide)
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.
#include < iostream >
#define MY_CHK_DEF(flag) \
#ifdef (flag) \
std::cout<<#flag<<std::endl; \
#else \
std::cout<<#flag<<" ,flag not define"<<std::endl; \
#endif
int main()
{
MY_CHK_DEF(FLAG_1);
MY_CHK_DEF(FLAG_2);
MY_CHK_DEF(FLAG_3);
...
}
complier report:
main.cpp:3:24: error: '#' is not followed by a macro parameter
any ideas?
Thanks
You can't do it. #if, #else, and #endif must be the first tokens on the logical line. Your definition is just one logical line, so it doesn't work,
You have to do it the other way round(defining the macro for each #if/#ifdef/#else condition(if you nest you have to put a definition on each branch). You probably should define it at every logical branch or it will fail to compile when you try to adjust a rarely adjusted flag. You can #define noops like this. Note to be careful not to wrap expressions with side effects into #define 'd macros that reduce to a noop when the debug flag is on, or your program may not work right.
#define N(x)
#include < iostream >
#ifdef (flag)
#define MY_CHK_DEF(flag)
std::cout<<#flag<<std::endl;
#else
#define MY_CHK_DEF(flag) \
std::cout<<#flag<<" ,flag not define"<<std::endl;
#endif
int main()
{
MY_CHK_DEF(FLAG_1);
MY_CHK_DEF(FLAG_2);
MY_CHK_DEF(FLAG_3);
...
}
C preprocessor is single-pass and #define creates a pretty dumb replacement that isn't further processed - your MY_CHK_DEF(flag) macro inserts the #if statement inline into preprocessed code that is interpreted by C compiler and not valid C.
You can either rephrase it to be one-pass, or if you can't, run through preprocessor twice, manually - once through cpp -P and the second time through normal compilation process.
You actually can do this if you use BOOST processor header lib.. it provides a BOOST_PP_IF macro allow this type of decisions.
http://www.boost.org/doc/libs/1_53_0/libs/preprocessor/doc/ref/if.html
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;
}