C++ 预处理器未按预期处理定义

标签 c++ macros clang preprocessor

我在使用 cpp 预处理器时遇到问题。我有这样的 Input.h 文件:

#ifndef PLATFORM_MOBILE1111
    #define MyTest WEB111
#endif 

int MyTest;

我用这个命令处理它(在 OSX 上):

cpp -E -P Source/Input.h Generated/Output.h

我明白了:

    #define MyTest WEB111


int MyTest;

宏 MyTest 未被应用。为什么?


经过大量实验,我发现如果我在#ifndef 行之后插入空行、变量定义、注释或任何其他行 - 那么它就可以正常工作。

#ifndef PLATFORM_MOBILE1111

    #define MyTest WEB111
#endif 

int MyTest;

所以上面的输入被正确处理成:

int WEB111;

有人可以向我解释为什么会这样吗?以及如何解决?有没有我可以通过的选项?


编辑:我还发现##(连接运算符)也不起作用!

最佳答案

奇怪!您显然在 clang 预处理器中发现了一个错误!

我也可以在 OSX 上重现它(Apple LLVM 版本 8.1.0 (clang-802.0.42))。

当您删除 #define(缩进)之前的空格时,这也会按预期开始工作,但前导空格根本不重要,而且很多编辑器缩进 #defines#ifdefs 中。

关于正在发生的事情的一个暗示是,在伪造的版本中,#define 仍然存在于处理过的源代码中,而在正确的版本中则不是。很显然,预处理器根本没有识别出 #define

即使这样也失败了(注意前导空格):

 #define MyTest WEB111
int MyTest;

虽然这按预期工作:

#define MyTest WEB111
int MyTest;

这导致 WEB222:

 #define MyTest WEB111
 #define MyTest WEB222
int MyTest;

虽然这会导致 WEB111:

#define MyTest WEB111
 #define MyTest WEB222
int MyTest;

疯了!1!! :-)

似乎总是忽略第一个缩进的#define

现在是“解决方案”:使用:

gcc -E Source/Input.cpp -P -o Generated/Output.cpp

虽然它使用相同的 LLVM,但它按预期工作。

所以我假设 gcc 可执行文件初始化预处理器的方式与 cpp 不同。这仍然是 cpp 中的错误。

关于C++ 预处理器未按预期处理定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46001337/

相关文章:

c++ - 在 C++ 中遍历可能包含 0xff 的十六进制输入

c++ - 链接器找不到命名空间的函数

c++ - "NULL pointer is passed"用于检测轮廓

c++ - 可用编译器的 Homebrew 列表

c++ - 你能 static_assert 一个元组只有一种类型满足特定条件吗?

macros - 使用 Lisp 宏创建类似的函数

c - C 中的宏和前/后增量

c++ - Qt4中宏的继承

c++ - 将代码从 gcc 移植到 clang

c++ - 为什么字符串连接宏不适用于这个 "+"案例?