为什么 c++ 命名空间中的定义在命名空间之外工作

Why the defines inside a c++ namespace works outside the namespace?

本文关键字:命名空间 工作 c++ 为什么 定义      更新时间:2023-10-16

如果我在命名空间中使用一些宏定义,那么它们为什么要在命名空间之外工作?例如,检查此代码:

#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 的干扰。但为什么要这样做呢?

"...当尝试声明 int a 时,它会受到先前定义的 A 的干扰。但为什么要这样呢?

#define语句由没有命名空间(或任何其他 C++ 语言构造)概念的 c/c++ 预处理器解释。

如果要限制定义的范围,请使用 #undef 指令:

namespace foo {
    #define a x*2
    int f(int x) {
        return a;
    }
    #undef a
 // ^^^^^^^^
}

预处理器不知道任何高级语言功能,如命名空间或作用域。它只是查找以#开头的行,然后进行简单的文本替换。这就是为什么将预处理器用于除#include或文件保护之外的任何内容在C++中都是危险的一个原因。

#define

尊重任何C++范围。没有"local" #define这样的东西.它将一直有效,直到它被#undef-ed

namespace foo {
    #define a x*2
    int f(int x) {
        return a;
    }
    #undef a              <<<<<<<<<<<<<<<<<<<<<
}

C 预处理器几乎是它自己的一种语言。它首先执行。宏创建传递到实际 C/C++ 编译器的代码。每当使用宏时,请始终记住宏胜过一切,甚至是大括号。只有另一个预处理器指令(如 #undef)可以停止宏。

顺便说一句,您甚至可以在任何文本文件上单独使用 C 预处理器。