代码之家  ›  专栏  ›  技术社区  ›  Angew is no longer proud of SO

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

  •  25
  • Angew is no longer proud of SO  · 技术社区  · 8 年前

    为什么要将名称添加到 std 命名空间未定义的行为?

    显而易见的答案是“因为标准如此”,例如在C++14[namespace.std]17.6.4.2.1/1中:

    如果C++程序向名称空间添加声明或定义,则其行为是未定义的 标准 或发送到 命名空间内的命名空间 标准 除非另有规定。。。

    然而,我对这一裁决的原因很感兴趣。我当然可以理解在中添加名称重载 标准 可能破坏行为;但为什么添加新的、不相关的名称是一个问题?

    程序已经可以在内部造成破坏 标准 对于宏,这就是为什么几乎所有标准库实现都必须只包含所有非公共部分的保留名称(双下划线和起始下划线后跟大写)的原因。

    我真的很想了解这样一种情况:

    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 回复  |  直到 8 年前
        1
  •  12
  •   Eugene    4 年前

    以下是几个原因:

    1. 即使姓名在 标题 必须丑化以避免与宏交互,在实际实现代码的源文件中,对于名称不存在此要求。如果实现确实使用 ::std::foo(int) 作为其实现的一部分,这将违反一个定义规则。
    2. 该标准有望提高。如果名称可以添加到命名空间 std 添加到标准C++库中的任何名称都可能是一个破坏性的更改。从某种意义上说,任何这样的名称都可能是一个宏的角度来看,这已经是事实,但打破这些名称是可以接受的。
    3. 实际上不需要向名称空间添加名称 标准 :它们可以添加到任意的其他名称空间,即,即使上面给出的动机不是特别强烈,也不会以任何形式考虑限制……如果存在 向名称空间添加名称的原因 标准 ,很明显 影响行为。