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()
代码内定义的,因此它输出 yes
。 main()
中的 #undef
对 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();
}
#include<iostream>
int main(){
std::cout<<"yes\n";
std::cout<<"no\n";
}
我有两个程序来测试 #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()
代码内定义的,因此它输出 yes
。 main()
中的 #undef
对 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();
}
#include<iostream>
int main(){
std::cout<<"yes\n";
std::cout<<"no\n";
}