When do we need #ifdef before #undef?
Asked Answered
C

3

39

In many of the C and C++ files I have seen macros like this:

#ifdef X
#undef X  // no statements in between
#endif

I feel that, it's adequate to simply write:

#undef X

If the macro X wasn't defined, then the #undef should have no effect.

Is it ok to put standalone #undef, if I want to only undefine a macro ? Does that make the coding practice bad in anyway ?

Continence answered 1/2, 2012 at 3:56 Comment(5)
I agree; I just did a quick search and this behaviour seems to be consistent across the major compilers. Perhaps some historically did not allow you to undef an undefined macro? Not sure. I'd say that it's probably safe.Seedcase
Seems to me that it is fine all by itselfSidwell
I think I remember atleast MSVC erroring out on me with that.Leesa
@Xeo, maybe in the past. MSDN reckons that it's OK as of VS2005.Seedcase
@anthony: The docs actually say it's valid as far back as VS 2003. It's probably VC 6 he's thinking of, notorious for its lack of standards compliance.Jink
A
26

See ISO C99 6.10.3.5 paragraph 2.

A preprocessing directive of the form

# undef identifier new-line

causes the specified identifier no longer to be defined as a macro name. It is ignored if the specified identifier is not currently defined as a macro name.

Even Visual C++ 6 (which was notorious for bad standards compliance) allows this:

You can also apply the #undef directive to an identifier that has no previous definition. This ensures that the identifier is undefined. Macro replacement is not performed within #undef statements.

Adust answered 1/2, 2012 at 4:8 Comment(1)
I can confirm that this is exactly the same for ISO C++11 as well.Seedcase
A
12

I'm sure it's an artifact of history. As mentioned in jdigital's answer, the 2nd edition of K&R says

It is not erroneous to apply #undef to an unknown identifier.

However, that sentence is not in the 1978 edition. I'm pretty sure pre-standard compilers would often throw an error if you tried to #undef an undefined macro.

Also, the ANSI C Rationale says:

It is explicitly permitted to #undef a macro that has no current definition.

I'd imagine that if it was already universal practice, there would be no need to call it out in the rationale.

All that said, it's not necessary in modern code, but it doesn't really hurt either.

Alkali answered 1/2, 2012 at 5:10 Comment(4)
I have no evidence but I'd wager that the C compilers of that era (first edition) would not throw an error. It wouldn't fit with the Unix philosophy.Sulphuryl
How's this for obsessive: I managed to Google-up an old DeSmet-C compiler for MS-DOS (ver 2.4 from 1984!), and it throws an error when I #undef FOO -- 3 # $$ undef FOO / error:not definedAlkali
You win! (MS-DOS people clearly didn't get the Unix philosophy.)Sulphuryl
@MichaelBurr: please post your comment as an answer. I'd like to give you some rep for this.Adust
S
9

Kernighan and Ritchie (2nd edition) agree with you.

EDIT: quote from the source (section A12.3):

A control line of the form

# undef identifier

causes the identifier's preprocessor definition to be forgotten. If is not erroneous to apply #undef to an unknown identifier.

Sulphuryl answered 1/2, 2012 at 4:3 Comment(2)
Can you quote from the source?Seedcase
@anthony-arnold: quoted from source as requested.Sulphuryl

© 2022 - 2024 — McMap. All rights reserved.