C++ #定义空值

C++ #定义空值,c++,c,null,macros,C++,C,Null,Macros,此代码在gcc中编译,没有警告/错误。有人能解释一下预处理器在这里做什么吗?这很正常: #ifndef NULL #define NULL NULL #endif 这也可以编译。这是因为预处理器只是进行无意识的替换。它替换的内容和替换的内容不需要是有效的标识符 可以这样想:打开编辑器的搜索和替换窗口,在Replace和Replace with字段中键入“NULL”。它不会给出任何错误或警告,它会“工作”,即使它实际上什么都不做。预处理器做同样的事情 显然,当您尝试使用它时: #ifndef J

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

这很正常:

#ifndef NULL
#define NULL NULL
#endif
这也可以编译。这是因为预处理器只是进行无意识的替换。它替换的内容和替换的内容不需要是有效的标识符

可以这样想:打开编辑器的搜索和替换窗口,在
Replace
Replace with
字段中键入“NULL”。它不会给出任何错误或警告,它会“工作”,即使它实际上什么都不做。预处理器做同样的事情

显然,当您尝试使用它时:

#ifndef JON_SKEET
#define JON_SKEET JON_SKEET
#endif
“JON_SKEET”未声明(首次在此函数中使用) (每个未声明的标识符只报告一次。) 对于中显示的每个函数。)
只要编译器看到文本“NULL”,它就会用文本“NULL”替换它。这就像在代码中搜索并替换“NULL”并替换为“NULL”。不是非法的,只是奇怪:)

这不是简单地将NULL定义为字符序列“NULL”吗?

显然这不是用作宏,而是用作编译标志。在代码的其他区域是否可以看到
#ifdef NULL
#ifndef NULL


使用“NULL”是非常奇怪的,特别是作为这样的标志,但我见过陌生人(
#define TRUE FALSE
)…

这样做的唯一可能原因是在包含头文件之前这样做,头文件本身做类似于

'JON_SKEET' undeclared (first use in this function) (Each undeclared identifier is reported only once for each function it appears in.)
这将阻止空值被这样定义。

在回答预处理器正在做什么的问题时:


除非前面的代码未定义NULL,否则它将完全跳过
#define NULL NULL
。几乎可以肯定已经定义了NULL。在C++中,由于C++的更紧凑类型检查,使用0是首选。如果必须使用NULL,最好声明
const int NULL=0(请参阅Stroustrup的第5.1.1节)。

< P>我见过这样的代码,它将编译器命名空间(“命名空间”,而不是C++ >代码>命名空间< /代码>)的值引入预处理器命名空间,例如:

//在编译器命名空间中,而不是在预处理器命名空间中
静态int const FOO=1234;
//将常量也带到预处理器命名空间中

#ifndef FOO//是的,但是这样的块通常意味着符号定义的事实才是重要的。对NULL这样做很奇怪。不是真的,这不是一个要求。不。当你说字符序列和使用引号时要小心,因为你可能指的是一个c字符串数组
“NULL”
。NULL并不意味着在c/c++中未定义……这可能比define六十九69强。尝试执行:#ifndef NULL#定义NULL 0#endif@TripleS-我从来不会在生产代码中这样做。我只是在某处看到它,觉得它很有趣,值得思考。事实上,我在某处也看到了它。。。我不会把它作为最终解决方案。据说在C++开始时,null被定义为零。先生,我赞成你的化身。我很久没有想到LimMeNes了。这难道不只是提出一个更神秘的问题,为什么你想阻止NULL被定义在某个其他的头上?这个问题也被标记为C++,在他的书的5.1.1中,Stroustrup推荐了下面的定义:<代码> const int null=0;<代码>我认为重要的是要注意,除非未定义NULL,否则它几乎肯定不会这样做。NULL通常是被定义的,所以这个块可能没有任何作用。嗯,我以为我在那里有一个用途,但后来我意识到它是错误的。如果已经定义了FOO,那么它将在行
static int const FOO=1234中被替换。我不知道你为什么会准备在这种情况下继续下去
#define FOO FOO
如您所说,如果您要用常量替换宏,但不想更改一些检查定义宏的旧代码,则可能有意义。但是,当你定义常量FOO时,让FOO被定义为其他的东西对我来说似乎是个麻烦。
#ifndef NULL
#define NULL (void *)0
#endif
// 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