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

Abh*_*ngh 0 c++ macos c-preprocessor

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

测试1.cpp

#include<iostream>

#define AB 1

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

int main(){
display();
#undef AB
display();
}
Run Code Online (Sandbox Code Playgroud)

输出: yes yes

测试2.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
}
Run Code Online (Sandbox Code Playgroud)

输出 : yes no

即使两个程序的逻辑相同,为什么输出也会有所不同?定义和取消定义宏线程安全吗?

Rem*_*eau 5

这两个程序不一样!

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

关于线程安全,在预处理编译阶段不涉及线程,只有在运行时实际执行最终编译的程序时才涉及。

所以,在你的例子中:

在第一个程序中,从上到下,AB定义,然后到达display()代码,然后main()到达,和#undef内在。因为ABdisplay()代码内部定义,它输出yes. 该#undefmain()有什么内部的发生没有影响display(),因为#undef是后display()的代码。由于main()两次调用display(),您会看到yes打印了两次。

在第二个程序中,从上到下移动,AB被定义,然后main()被输入,并且AB是为产生第一个输出的代码定义的,所以它打印yes,但AB对于产生第二个输出的代码是未定义的,所以它no改为打印。

如果您手动执行预处理器所做的相同替换,您将看到您有两个截然不同的程序:

#include<iostream>

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

int main(){
display();
display();
}
Run Code Online (Sandbox Code Playgroud)
#include<iostream>

int main(){
std::cout<<"yes\n";
std::cout<<"no\n";
}
Run Code Online (Sandbox Code Playgroud)