CIsForCookies
CIsForCookies

Reputation: 12837

whats happens when using #define with no replacement string?

When trying to debug my code, I marked a few printf with this:

#if debug
    printf(...);
#endif

And at the start of the file, I mistakenly wrote #define debug instead of #define debug 1

gcc threw the following error:

error: #if with no expression

Now I have 2 options:

  1. changing the define into #define debug 1
  2. changing the if into #ifdef debug

I know that upon seeing #define debug 1 the PP will replace each debug in my code to 1 and that's why #if debug in my code didn't work - the compiler sees no expression...

My question is, when I use #ifdef debug - what happens? I figure debug is saved somewhere and checked, but where and how?

Upvotes: 4

Views: 1476

Answers (2)

ad absurdum
ad absurdum

Reputation: 21361

The relevant syntax for the #define preprocessing directive is spelled out in §6.10 ¶1 (C11 Draft Standard):

# define identifier replacement-list new-line
...
replacement-list: pp-tokensopt

The semantics of the #define directive are found in §6.10.3:

A preprocessing directive of the form

# define identifier replacement-list new-line

defines an object-like macro that causes each subsequent instance of the macro name to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive. The replacement list is then rescanned for more macro names as specified below.

Note that a replacement-list is optionally composed of preprocessing tokens, and thus may be empty. So, to consider a footnoted example from the Standard:

#define EMPTY

Since, according to §6.10.3 ¶7:

The identifier immediately following the define is called the macro name. There is one name space for macro names.

the macro name EMPTY has been defined, and exists in the namespace for macro names. Each subsequent instance of EMPTY will be replaced by no preprocessing tokens.

Upvotes: 3

user2371524
user2371524

Reputation:

It's actually quite simple: #define debug does define debug to be empty. It is still defined. An empty macro is different from one that doesn't exist. #undef debug would remove the macro.

#ifdef doesn't care about the value. It only checks whether the macro is defined to whatever. If you don't care about the value, always use #ifdef.

Upvotes: 6

Related Questions