#ifndef NULL
#define NULL NULL
#endif
此代码在gcc中编译,没有警告/错误。有人可以解释预处理器在这里做了什么吗?
答案 0 :(得分:19)
编译器看到文本“NULL”的任何地方,它将用文本“NULL”替换它。这就像在代码中搜索和替换“NULL”并替换为“NULL”。不违法,只是奇怪:)
答案 1 :(得分:14)
这样做的唯一可能原因是之前包括头文件,它们本身就像
#ifndef NULL
#define NULL (void *)0
#endif
这样就可以阻止NULL被定义为。
答案 2 :(得分:5)
这是正常的:
#ifndef JON_SKEET
#define JON_SKEET JON_SKEET
#endif
这也是编译。这是因为预处理器只是无意义的替换。它取代的内容和替换内容不需要是有效的标识符。
这样想:打开你的编辑器的搜索&替换窗口并在Replace
和Replace with
字段中键入“NULL”。它不会给出任何错误或警告,它会“工作”,即使它实际上没有做任何事情。预处理器做同样的事情。
显然,当你尝试使用它时:
'JON_SKEET' undeclared (first use in this function) (Each undeclared identifier is reported only once for each function it appears in.)
答案 3 :(得分:3)
我见过像这样的代码将编译器命名空间(通常是“命名空间”,而不是C ++ namespace
)的值带到预处理器命名空间的情况,例如:
// In the compiler namespace, not in the preprocessor namespace
static int const FOO = 1234;
// Bring the constant into the preprocessor namespace as well
#ifndef FOO // <---- FOO really is undefined here.
#define FOO FOO
#endif
非常丑陋的东西。
就我个人而言,我还没有找到这种用途的用途,但仍然存在。
编辑:虽然我已经看过这个,但我不知道为什么它会有用,除了检查“FOO
”是否定义为预处理器符号在其他地方码;也许在处理一些遗留代码时。任何人吗?
答案 4 :(得分:2)
显然,这不是用作宏,它被用作编译标志。代码的其他区域是否显示#ifdef NULL
或#ifndef NULL
?
使用“NULL”是非常奇怪的,特别是作为这样的标志,但我见过陌生人(#define TRUE FALSE
)......
答案 5 :(得分:1)
回答预处理器正在做什么的问题:
除非前面的代码是undefs NULL,否则它会完全跳过#define NULL NULL
。几乎肯定已经定义了NULL。在C ++中,由于C ++的类型检查更严格,因此优先使用0。如果必须使用NULL,最好声明const int NULL = 0;
(参见Stroustrup的第5.1.1节)。
答案 6 :(得分:0)
不是简单地将NULL定义为字符序列“NULL”吗?