Double nested parentheses throw an error inside macro when using the defined operator

239 views Asked by At

I am writing an emulator and I want it to be exactly like macros in C. The following code confuses me:


This is valid code and returns true:

#if ((((1 + ((2)))))) == 3

This is also valid code and returns true:

#define hi hello
#if defined (hi)

But this will throw an error and not compile:

#define hi hello
#if defined ((hi))

Is there a special reason why this does not work? It seems like it should work.


Here is a link if you want to test macros online: https://godbolt.org/ (put -E as argument)
Here a link that explains the defined operator: https://gcc.gnu.org/onlinedocs/gcc-8.4.0/cpp/Defined.html

2

There are 2 answers

2
DevSolar On BEST ANSWER

#if does a mathematical evaluation. Your parenthesis get evaluated as in a C expression. The more the merrier, they don't change the value the expression evaluates to (except when they do, of course, when set to change operator precedence).

#ifdef identifier / #if defined identifier / #if defined( identifier ) (the parenthesis are optional for the defined operator, and not allowed for #ifdef) checks if the given identifier is defined. An identifier begins with a letter or an underscore, and contains only letters, underscores, or digits.

hi is an identifier.

(hi) is not.

0
Eric Postpischil On

C 2018 6.10.1 specifies the behavior of define in a #if or #elif directive. It says the expression that controls conditional inclusion:

… may contain unary operator expressions of the form

defined identifier

or

defined ( identifier )

which evaluate to 1 if the identifier is currently defined as a macro name…

Thus, the operand of defined is not a general C expression but is onlyidentifier” or “( identifier )”.