gpt4 book ai didi

c++ - 为什么 公开 std 命名空间之外的实体?

转载 作者:行者123 更新时间:2023-12-01 14:48:29 37 4
gpt4 key购买 nike

据我了解,C++ 使用的 C 实体类似于 <math.h> 中的那些可以安全地包含在 std 中通过包含其对应的命名空间 <c...>变体(显然除了宏)。 cppreference seems to confirm this .

但是,包括<cmath>似乎拉入了 logstd 之外运行命名空间:

#include <cmath>

namespace log {}

int main() {}

编译自g++ -Wall -Wextra -pedantic -std=c++17 a.cpp产量:

a.cpp:3:11: error: ‘namespace log { }’ redeclared as different kind of entity
3 | namespace log {}
| ^~~
In file included from /usr/include/features.h:446,
from /usr/include/x86_64-linux-gnu/c++/9/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h:524,
from /usr/include/c++/9/cmath:41,
from a.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:104:1: note: previous declaration ‘double log(double)’
104 | __MATHCALL_VEC (log,, (_Mdouble_ __x));
| ^~~~~~~~~~~~~~

我的标准库坏了吗?我可以做些什么来避免这种情况吗?


我最初是使用 <random> 偶然发现的,这意味着更多的 header 可能会受到在顶级命名空间中喷出的明显随机 C 实体的影响。

最佳答案

Why does <cmath> expose entities outside the std namespace?

因为历史。

<cmath> header 是从 C 标准库继承的 header (在其中命名为 <math.h> )。在C语言中,只有声明所有名称的全局命名空间1

由于许多 C++ 实现也是 C 实现,它们通常通过按原样包含它来实现继承的 C 标准头文件2,这意味着它声明全局名称。

虽然可能有一些技术可以避免(标准宏的情况除外)声明全局名称,但自标准化之前就一直这样做的实现不太可能改变行为,因为这会破坏向后兼容性。

Is my standard library broken?

没有。 C++ 标准允许这样做;所有 C 标准库名称都保留供语言实现使用(或任何)使用。您可能不会自己定义它们。

Can I do something to avoid this?

您通常无法阻止标准库执行此操作。

您可以通过选择使用独立语言实现从技术上避免大部分问题。但如果您选择那样,您将失去几乎整个标准库。

您可以通过避免自己声明任何全局名称来最大程度地减少名称冲突的可能性,但具有足够唯一名称的单个命名空间除外。像这样的东西:

namespace usr_bitmask::log {

}

1 请注意,C 语言中的“命名空间”概念是另外一回事。

2 此外,在 std 中重新声明名称使用 <c... 时的命名空间命名 header ,并在某些情况下添加特定于 C++ 的重载。

关于c++ - 为什么 <cmath> 公开 std 命名空间之外的实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60765644/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com