【问题标题】:What are the reasons that extending the std namespace is considered undefined behavior?扩展 std 命名空间被视为未定义行为的原因是什么?
【发布时间】: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


【解决方案1】:

这里有几个原因:

  1. 即使 headers 中的名称必须被丑化以避免与宏交互,但实际实现代码的源文件中的名称并不存在此要求。如果某个实现确实使用::std::foo(int) 作为其实现的一部分,那将违反单一定义规则。
  2. 该标准有望增长。如果名称可以添加到命名空间std,那么添加到标准 C++ 库的任何名称都可能是一个重大更改。在某种程度上,这已经是正确的,因为任何这样的名称都可以是一个宏,但打破这些名称被认为是可以接受的。
  3. 实际上没有必要将名称添加到命名空间std:它们可以添加到任意其他命名空间,即,即使上面给出的动机不是特别强烈,任何形式的限制都不重要. ...如果 有理由向命名空间 std 添加名称,那么它显然确实会影响行为。

【讨论】:

  • 关于实现源文件的优点:我相信这正是我忽略的事情。
  • 虽然这不会影响程序的行为,但实现可能选择从字面上采用标准。例如,libstdc++ 将其变量之一命名为 Container c,因为这是标准中所说的,尽管您通常认为它会被丑化。
  • @sleeptightpupper:我认为标准库中的任何 exposition only 内容都不会导致保留名称。可能没有正式的规范,但我认为这些声明是非规范的,因此不保留名称。相关条款(17.5.2.3,[objects.within.classes])没有明确说明,但我认为它在第一段中是隐含的。
  • @sleeptightpupper 我们在谈论容器适配器,是吗?这些是protected 成员,所以名称是界面的一部分。
猜你喜欢
  • 2017-04-25
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 2014-02-25
  • 2013-12-11
相关资源
最近更新 更多