开发者

Why does defined(X) not work in a preprocessor definition without a space?

A preprocessor definition that includes defined(X) will never evaluate to true, but (defined X) will. This occurs in MSVC9; I have not tested other preprocessors. A simple example:

#define FEATURE0 1
#define FEATURE1 0
#define FEATURE2 1

#define FEATURE3 (FEATURE0 && !FEATURE1 && (defined(FEATURE2)))
#define FEATURE4 (FEATURE0 && !FEATURE1 && (defined FEATURE2))
#define FEATURE5 (FEATURE0 && !FEATURE1 && (defined (FEATURE2)))

#if FEATURE3
#pragma message("FEATURE3 Enabled")
#elif (FEATURE0 && !FEATURE1 && (defined(FEATURE2)))
#pragma message("FEA开发者_StackOverflowTURE3 Enabled (Fallback)")
#endif

#if FEATURE4
#pragma message("FEATURE4 Enabled")
#elif (FEATURE0 && !FEATURE1 && (defined FEATURE2))
#pragma message("FEATURE4 Enabled (Fallback)")
#endif

#if FEATURE5
#pragma message("FEATURE5 Enabled")
#elif (FEATURE0 && !FEATURE1 && (defined (FEATURE2)))
#pragma message("FEATURE5 Enabled (Fallback)")
#endif

The output from the compiler is:

1>FEATURE3 Enabled (Fallback)

1>FEATURE4 Enabled

1>FEATURE5 Enabled

Working cases: defined (X), defined( X ), and defined X.

Broken case: defined(X)

Why is defined evaluated differently when part of a definition, as in the #if cases in the example, compared to direct evaluation, as in the #elif cases in the example?


defined is specific to #if and #elif. When using it through macro expansion the behavior is undefined.


Remember that defined(X) isn't interpreted like a function call (a la sizeof(X)), it's parsed by a special language parser. This parser recognizes defined as a modifier to an if statement, not as an independent entity. When you are using defined(FEATURE2), it is not treating defined as a keyword but instead as a regular object or #defined entity (which doesn't exist in this case, causing your error). Later, when you use it inside the elif statement, the parser treats it as a proper keyword.

To be honest, I wasn't aware that defined(SOMETHING) would work in any case.


According to 6.10.1.3 in the C99 spec, the keyword defined is only recognized if it appears directly in the expression of the #if before any macro expansion in that expression. If macro expansion results in the keyword defined, the results are undefined.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜