扩展std命名空间被认为是未定义的行为的原因是什么?

时间:2016-05-31 08:49:47

标签: c++ undefined-behavior c++-standard-library

为什么在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

这种未定义行为的基本原理是什么?

1 个答案:

答案 0 :(得分:8)

以下是一些原因:

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