WebIDE treats #ifdef different to #if defined - Why?

I’m in the middle of porting an Adafruit library and use Web IDE for quick syntax/definition checks.
But then I stumbled accross an oddity of the preprocessor - I guess

#ifdef SPARK
#define thisWorks
#endif

#if defined SPARK
#define thisWorksToo
#endif

#if defined (SPARK)
#define thisWorksAsWell
#endif

#ifdef (SPARK)
#define butThisDoesNot
#endif

The last version does produce an error

fail.cpp:13:8: error: macro names must be identifiers

Why? I thought #ifdef and #if defined are absolutely exchangable, or aren’t they?

I found dis: http://stackoverflow.com/questions/1714245/difference-between-if-definedwin32-and-ifdefwin32 but I’m not entirely sure it’s relevant

1 Like

I see :eyes:

When I looked around I mainly got people saying they are the same - as I thought myself too.
But this would suggest, that #if defined is not actually an preprocessor directive, but only #if and defined acts more like a boolean function which takes its “parameters” with or without parentheses.

I never looked at it this way - but it makes sense!

Thanks

The key difference is that #if expects an expression, and so allows simple logical operators, functions, parentheses etc… so defined(SPARK) is valid is a valid expression. #ifdef expects simply an identifier to look up the name in the preprocessor’s symbol table of macro names. #ifdef is a syntactic shortcut, and not exactly the same as a text substitution.

What happens if you write #if defined ((SPARK)) - one might hope you get the same error since it willl strip of the outermost parentheses to leave (SPARK) as the symbol. Although it might not, depending upon how the grammar is defined for the preprocessor.

2 Likes