Tob*_*ght 5 c++ gcc namespaces
当我在 C++ 中使用标准 C 头文件时,我通常更喜欢将标识符放入std命名空间的形式,例如<cstdlib>. 但是,当我使用这些时,GCC 也会将名称放入全局命名空间中,这意味着它会接受这样的程序:
#include <cstddef>
std::size_t x;
size_t y;
int main() {}
Run Code Online (Sandbox Code Playgroud)
在这里,声明x是正确的,但是y如果我希望我的代码是可移植的,应该拒绝声明。(请注意,如果我包含<stddef.h>而不是<cstddef>,GCC将正确拒绝 的声明x)。
我可以让 GCC 拒绝上述声明y吗?
我编译了所有我能想到的迂腐和警告:
-std=c++17 -pedantic -Wall -Wextra -Wpedantic -Weffc++
Run Code Online (Sandbox Code Playgroud)
这些似乎都没有阻止 GCC 接受不可移植的形式。
我现在不确定我是否正确理解了规则;我的知识来自 CPP 参考中的这一部分:
C 兼容性头文件
对于某些形式的 C 标准库头文件
xxx.h,C++ 标准库都包括一个同名的头文件和另一个形式的头文件cxxx。除了
complex.h,xxx.hC++ 标准库中包含的每个标cxxx头都将相应标头放置在std命名空间中的每个名称都放在全局命名空间中。允许这些头文件在
std命名空间中也声明相同的名称,相应的cxxx头文件也允许在全局命名空间中声明相同的名称:包括<cstdlib>绝对提供std::malloc和也可能提供::malloc。包括<stdlib.h>肯定提供::malloc和也可能提供std::malloc。这甚至适用于不属于 C 标准库的函数和函数重载。
对我来说,最后一段表明 GCC 的行为是允许的,但不是必需的,因此依赖它是错误的。
规则是#include <xxx.h>(其中xxx.h是标准 C 标头的名称)需要在全局命名空间中定义 C 标准所需的该标头的所有名称,并且还允许在命名空间std。类似地,#include <cxxx>(其中cxxx是标准 C 库的标准 C++ 头文件之一的名称) 需要定义命名空间中相应 C 头文件(具有相同含义)的所有名称std,并且还允许定义这些名称在全局命名空间中。
早在 C++ 98 中,这些标头不允许将名称添加到其他命名空间。有些编译器无法做到这一点。例如,如果 C++ 库编写者不控制 C 标头,则通常的实现技术是将 C++ 标头添加到#includeC 标头,并将 C 名称提升到stdusing 声明中。因此规则被改变以反映现实。
语言定义不要求这些标头将名称放在两个位置;如果是这样,那么就cxxx不需要标题了。
简而言之,您不能指望#include <cxxx>将 C 名称放入全局名称空间,但也不能指望它不将它们放在那里。
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |