如果我在命名空间中使用某些宏定义,那么为什么它们应该在命名空间之外工作?检查此代码,例如:
#include <bits/stdc++.h>
namespace foo {
#define a x*2
int f(int x) {
return a;
}
}
int main() {
int a = 50;
std::cout << a << endl;
std::cout << foo::f(4) << endl;
return 0;
}
这里我从未使用命名空间foo编写过。但是仍然没有编译这段代码,因为当尝试声明int a时,它会受到先前定义的a的干扰。但为什么会这样呢?
答案 0 :(得分:6)
&#34; ...当尝试声明int a时,它会受到先前定义的a的干扰。但为什么会这样呢?&#34;
#define
语句由c / c ++预处理器解释,它没有命名空间(或任何其他c ++语言结构)的概念。
如果要限制定义的范围,请使用#undef
指令:
namespace foo {
#define a x*2
int f(int x) {
return a;
}
#undef a
// ^^^^^^^^
}
答案 1 :(得分:4)
预处理器不知道任何高级语言功能,例如命名空间或作用域。它只查找以#
开头的行,然后进行简单的文本替换。这就是为什么在{+ 1}}或文件保护中使用预处理器在C ++中很危险的一个原因。
答案 2 :(得分:3)
#define
不尊重任何C ++范围。没有"local" #define
这样的东西。它会一直有效,直到#undef-ed
。
namespace foo {
#define a x*2
int f(int x) {
return a;
}
#undef a <<<<<<<<<<<<<<<<<<<<<
}
答案 3 :(得分:1)
C预处理器几乎就是它自己的语言。它首先执行。宏创建传递给实际C / C ++编译器的代码。无论什么时候使用宏,都要记住,宏会胜过一切,甚至是花括号。只有另一个预处理程序指令(如#undef)可以停止宏。
BTW,您甚至可以在任何文本文件上单独使用C预处理器。