【发布时间】:2016-09-29 04:33:40
【问题描述】:
为什么将名称添加到 std 命名空间未定义行为?
显而易见的答案是“因为标准是这样说的”,例如在 C++14 [namespace.std] 17.6.4.2.1/1 中:
如果 C++ 程序将声明或定义添加到命名空间
std或 命名空间std中的命名空间,除非另有说明。 ...
但是,我真的很想知道这个裁决的原因。我当然可以理解在std 中添加重载名称可能会破坏行为;但为什么添加新的、不相关的名称会成为问题?
程序已经可以使用宏在std 内部造成严重破坏,这就是为什么几乎所有标准库实现都必须仅包含所有非公共部分。
我真的会对这样的事情可能有问题的情况感兴趣:
namespace std
{
int foo(int i)
{ return i * 42; }
}
#include <algorithm> // or one or more other standard library headers
当这是完全合法且标准库必须应对时:
#define foo %%
#include <algorithm> // or one or more other standard library headers
这种未定义行为的基本原理是什么?
【问题讨论】:
-
如果你决定需要
vector::random_iterator,你将它添加到std,在下一个版本中做出这些决定的聪明人会想:“嘿,让我们添加一个@987654330 @" 并让array_shuffle使用它。 -
@Angew “包含标准库头文件的翻译单元不得在任何标准库头文件中声明
#define或#undef名称”怎么样? (C++11、17.6.4.3.1)。 (不限于记录在案的名称。) -
@sleeptightpupper:实际上,标准确实 禁止您以任何形状或形式定义任何保留名称。标准 C++ 库中使用的所有语言关键字和所有名称(以及几个通用名称)都是保留的。
-
@molbdnilo 从技术上讲,它不仅限于文档名称,但这是否意味着您必须解析所有标准库头文件并在其中找到所有非公共名称,然后才能合法地定义宏?
-
将 UB 扩展 std:: 命名空间 以任何与未来 C++ 规范不一致的方式 的规则会有什么问题吗?这将允许人们通过向 std:: 添加与新规范将实现的功能相匹配的特性来调整为未来的 C++ 规范编写的代码,同时还允许编译器在仍然支持旧规范的同时添加新规范的特性。
标签: c++ undefined-behavior c++-standard-library