Reputation: 73041
Today I came across some C++ code that contains an #ifdef clause like this:
#ifdef DISABLE_UNTIL OTHER_CODE_IS_READY
foo();
#endif
Note the space between "DISABLE_UNTIL" and "OTHER_CODE_IS_READY". Essentially there are two tokens specified in the #ifdef line.
My question is, is this legal C++ code? (g++ compiles it without any errors, and it apparently just ignores the second token). And if it is legal, should the second token have any effect?
Upvotes: 6
Views: 10082
Reputation: 385098
[C++11 16.1]
, [C++11 16.5]
and, incidentally, [C99 6.10.1/4]
all say that this is invalid.
if-group:
# if
constant-expression new-line groupopt
# ifdef
identifier new-line groupopt
# ifndef
identifier new-line groupopt
Only one identifier is legal.
GCC's own documentation agrees.
My own tests suggest that only the first identifer is accepted, and the second is simply discarded; this may be to ease the implementation, but the standard does require a diagnostic here, so you should see this when you use the -pedantic
flag at least†.
#include <iostream>
using namespace std;
#define A
#define B
int main() {
#ifdef A
std::cout << "a ";
#endif
#ifdef B
std::cout << "b ";
#endif
#ifdef C
std::cout << "c ";
#endif
#ifdef B C
std::cout << "bc ";
#endif
#ifdef C B
std::cout << "cb ";
#endif
return 0;
}
// Output: "a b bc"
// Note: "cb" *not* output
† Coliru's installation of GCC emits it with or without -pedantic
.
Upvotes: 6
Reputation: 64672
The syntax you posted is not legal, and the intended meaning is unclear.
Depending on what you hope to accomplish, can you use ||
or &&
to combine them?
(of course if this is someone else's code, I'd just reject it as inappropriate / unusable)
#if defined(DISABLE_UNTIL) || defined(OTHER_CODE_IS_READY)
foo();
#endif
Upvotes: 14