Pregunta

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?

¿Fue útil?

Solución

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.

Otros consejos

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 ;

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top