0

Include guards in header files are often used to protect sections of code from double inclusion:

#ifndef FOOBAR_H
#define FOOBAR_H

extern void myfoofunc(void);

#endif

Include guards typically rely on the expectation that if an object-like macro was already defined, the lines within the #ifndef block will not included -- thus avoiding double inclusion.

I've noticed that the #define line for many include headers have empty replacement-lists. Does the C99 standard guarantee that object-like macros defined with an empty replacement-list will be considered "defined" by #ifndef?

When describing the syntax of #define, the C99 standard seems to imply that a replacement-list is required in section 6.10.3 paragraph 9:

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.

Does this mean include headers should instead be of the form: #define FOOBAR_H 1?

1
  • "the C99 standard seems to imply that a replacement-list is required " -- It does no such thing. Take a look at the definition of replacement-list.
    – Jim Balter
    Commented Jun 27, 2013 at 21:45

3 Answers 3

2

The standard syntax production for a replacement-list is: pp-tokens [opt]. So no tokens are necessary for a replacement-list to be valid.

So #ifdef will work fine and as expected for macros that are defined 'empty'. A ton of code depends on this.

1
  • Ah yes, I overlooked the Syntax listing in section 6.10 paragraph 1: replacement-list is defined as pp-tokens [opts] as you describe. Commented Jun 27, 2013 at 21:09
1

No, it doesn't. The replacement list may well be empty. #define FOO means that defined FOO is true, but FOO is replaced with nothing.

Example:

#define FOO
#define BAR 1

#if defined FOO && defined BAR
int a = FOO + BAR ;
#endif

Result of preprocessing:

int a = + 1 ;
10
  • In this case, would #if FOO == 1 succeed, or is the actual numerical value of FOO implementation defined? Commented Jun 27, 2013 at 21:04
  • 1
    The value of FOO is the empty string.
    – Kerrek SB
    Commented Jun 27, 2013 at 21:06
  • Does this mean the I'd get a compiler error if I use #if to try to compare it to a numerical value? Commented Jun 27, 2013 at 21:11
  • @VilhelmGray: You would. (Why aren't you trying this out yourself?!)
    – Kerrek SB
    Commented Jun 27, 2013 at 21:17
  • 1
    @VilhelmGray "In this case, would #if FOO == 1 succeed" -- That expands to #if == 1. "the actual numerical value of FOO" -- there is no such thing ... the preprocessor does textual/token expansion.
    – Jim Balter
    Commented Jun 27, 2013 at 21:48
0

No; the macro substitution will not take place in the #ifndef line. If it did, then the whole statement would be a syntax error (since there wouldn't be anything following the #ifndef).

I think I've actually seen some instances of #define FOOBAR_H 1 but that's more of a personal taste.

Not the answer you're looking for? Browse other questions tagged or ask your own question.