ifndef是否总是在使用空替换列表定义的类对象宏上工作

时间:2013-06-27 20:53:45

标签: c c99 c-preprocessor include-guards

头文件中的

Include guards通常用于保护代码段不被双重包含:

#ifndef FOOBAR_H
#define FOOBAR_H

extern void myfoofunc(void);

#endif

包含守卫通常依赖于这样的期望:如果已经定义了类似对象的宏,则#ifndef块中的行将不包括在内 - 从而避免双重包含。

我注意到许多包含标题的#define行都有空替换列表。 C99标准是否保证使用空替换列表定义的类似对象的宏将被#ifndef视为“已定义”?

在描述#define的语法时,C99标准似乎暗示第6.10.3节第9段中需要替换列表:

  

表单

的预处理指令      

#define 标识符替换列表换行

     

定义一个类似对象的宏,它会导致宏名称的每个后续实例   替换为预处理令牌的替换列表   构成指令的其余部分。替换列表是   然后重新扫描以获得更多宏名称,如下所示。

这是否意味着包含标题应该是以下形式:#define FOOBAR_H 1

3 个答案:

答案 0 :(得分:2)

replacement-list的标准语法制作是:pp-tokens [opt]。因此,替换列表无需令牌。

因此,对于定义为“空”的宏,#ifdef可以正常工作。大量代码依赖于此。

答案 1 :(得分:1)

不,它没有。替换列表可能是空的。 #define FOO表示defined FOO为真,但FOO替换为空。

示例:

#define FOO
#define BAR 1

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

预处理结果:

int a = + 1 ;

答案 2 :(得分:0)

没有;宏替换不会发生在#ifndef行。如果确实如此,则整个语句将是语法错误(因为#ifndef之后不会有任何内容。)

我想我实际上已经看到#define FOOBAR_H 1的一些例子,但这更像是个人品味。