C++ 取消定义宏未按预期工作

C++ undefine macros not working as expected

我有两个程序来测试 #undef 的工作,但它没有按预期工作。

test1.cpp

#include<iostream>

#define AB 1

void display(){
#ifdef AB
std::cout<<"yes"<<std::endl;
#endif
}

int main(){
display();
#undef AB
display();
}

输出:yes yes

test2.cpp

#include<iostream>

#define AB 1

int main(){
#ifdef AB
std::cout<<"yes\n";
#endif

#undef AB

#ifdef AB
std::cout<<"yes\n";
#else
std::cout<<"no\n";
#endif
}

输出:yes no

为什么两个程序的逻辑是一样的,但输出结果却不一样? 定义和取消定义宏也是线程安全的吗?

两个程序不一样!

预处理器宏在预处理阶段被解析和替换,在编译阶段甚至看到源代码之前。预处理器是一个 single-pass 操作,从上到下。 #define#undef 按照它们出现的顺序进行处理,并且可以改变编译器最终看到的源代码。

关于thread-safety,在预处理编译阶段不涉及线程,只有在最终编译程序时实际上是在运行时执行的。

因此,在您的示例中:

第一个程序中,从上往下移动,定义了AB,然后是display()代码,然后是main()#undef 在 in 内。由于 AB 是在 display() 代码内定义的,因此它输出 yesmain() 中的 #undefdisplay() 内部发生的事情没有影响,因为 #undefdisplay() 的代码之后。由于 main() 两次调用 display(),您会看到 yes 打印了两次。

在第二个程序中,从上往下移动,定义了AB,然后输入main(),为产生第一个输出的代码定义了AB,所以它打印 yes,但是 AB 对于生成第二个输出的代码是未定义的,因此它打印 no

如果您手动执行与预处理器相同的替换,您会发现您有两个截然不同的程序:

#include<iostream>

void display(){
std::cout<<"yes"<<std::endl;
}

int main(){
display();
display();
}
#include<iostream>

int main(){
std::cout<<"yes\n";
std::cout<<"no\n";
}