#define NULL NULL

时间:2009-12-22 22:38:39

标签: c++ c null macros

#ifndef NULL
#define NULL NULL
#endif

此代码在gcc中编译,没有警告/错误。有人可以解释预处理器在这里做了什么吗?

7 个答案:

答案 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

这也是编译。这是因为预处理器只是无意义的替换。它取代的内容和替换内容不需要是有效的标识符。

这样想:打开你的编辑器的搜索&替换窗口并在ReplaceReplace 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”吗?