问题
I had envisaged one of these in the project preferences
TESTING
=HOST
TESTING
=TARGET
TESTING
not defined at all
My problem is with the latter.
It seems that instead of
#if TESTING==HOST
#error "HOST defined" // add temporarilly for testing porpoises
#endif
I need to code
#ifdef TESTING
#if TESTING==HOST
#error "HOST defined" // add temporarilly for testing porpoises
#endif
#endif
I am convinced that this is not-standard behaviour, since if TESTING
is not defined then it certainly doesn't equal HOST
, and I do not need that extra #ifdef TESTING
with the GCC compiler.
However, when I use the Atmel AVR Studio (which I think is based on MS Visual Studio), it is necessary to add that initial #ifdef TESTING
in a few dozen places :-(
It looks like I have no choice, but I just wondered if any C standard acually requires this.
回答1:
#if TESTING==HOST
If TESTING
is not defined, then
it is equivalent to:
#if 0==HOST
From the C Standard:
(C99, 6.10.1p4) "After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0""
回答2:
And note that you can do this:
#ifndef TESTING
...
#elif TESTING == HOST
...
#elif TESTING == TARGET
...
#else
#error "Unexpected value of TESTING."
#endif
Also:
#if defined(TESTING) && TESTING == HOST
...
#endif
If you want to collapse the tests. The parenthesis are optional (#if defined TESTING
is valid) but I think it's clearer to include them, especially when you start adding additional logic.
回答3:
The original C preprocessors required explicit #ifdef
validation before using a symbol. It is a relatively recent innovation (perhaps driven by scripting languages like Javascript) to assume that undefined symbols have a default value.
Why don't you always insure the symbol is defined?:
#ifndef TESTING
#define TESTING (default value)
#endif
#if TESTING==HOST
...
#elif TESTING==TARGET
...
#else
...
#endif
Alternative, maybe force a selection?:
#ifndef TESTING
#error You must define a value for TESTING
#endif
回答4:
I had the same problem. It used to be the compiler would error if the #if parameter was not defined which is what I wanted. I learned the hard way this is no longer the case. The solution I came up with is as follows:
#define BUILDOPT 3
#if 3/BUILDOPT == 1
<compile>
#endif
If BUILDOPT is not defined you get a compile error for divide by 0. If BUILDOPT != 3 && > 0 the #if fails.
回答5:
My final implementation is to set BUILDOPT to 1 to enable the code, > 1 to disable. Then the #if becomes #if 1/BUILDOPT==1.
来源:https://stackoverflow.com/questions/13149189/preprocessor-equality-test-is-this-standard