Why does a specific (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 happens 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("FEATURE3 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 

Compiler output:

1> FEATURE3 Enabled (Return)
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 a part of the definition, as in the case of #if in the example, is compared with a direct assessment, as in the cases of #elif in the example?

+4
source share
3 answers

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

+5
source

Remember that defined(X) not interpreted as a function call (a la sizeof(X) ), it is parsed by a special language parser. This analyzer recognizes defined as a modifier for the if , and not as an independent object. When using defined(FEATURE2) , it is not treating defined as a keyword, but instead of like a regular object or #define q object (which does not exist in this case, resulting in your error). Later, when you use it inside the elif operator, the parser treats it as the correct keyword.

To be honest, I did not know that defined(SOMETHING) would work anyway.

+3
source

According to 6.10.1.3, in the specification C99, a defined keyword is recognized only if it is displayed directly in the #if expression before any macro extension in this expression. If macro expansion appears, the keyword , the results are undefined.

+1
source

Source: https://habr.com/ru/post/1304612/


All Articles