【问题标题】:Can reserved function names be overloaded?保留函数名可以重载吗?
【发布时间】:2018-06-19 09:54:16
【问题描述】:

这个问题是this one的后续问题。

考虑以下程序:

#include <cmath>

// meaningless, only for language-lawyer purpose
void abs(void*) {}

int main(){
    abs(nullptr);
}

这个程序会导致未定义的行为吗?


标准中相关部分为[extern.names]/4:

使用外部链接声明的 C 标准库中的每个函数签名都保留给实现,以用作具有 extern "C" 和 extern "C++" 链接的函数签名,或作为命名空间范围的名称全局命名空间

我不确定是否允许重载。

【问题讨论】:

  • 我不知道行为是否未定义,但肯定是出乎意料的。
  • 这是一个奇怪的段落。它以签名开始,这很清楚,然后是名称。
  • @Ron int abs(int);使用外部链接声明的 C 标准库中的函数签名。非粗体文本表示此签名是保留的;但是粗体部分继续说签名保留为名称,这没有意义
  • 一些“功能”有时被实现为marcos - 例如htons。虽然不是我所知道的“保留”功能,但它突出了一些实现的糟糕程度。
  • @UKMonkey:C++ 明确表示可以实现为函数或宏的 C 名称必须是 C++ 中的函数。但是,htons 不是标准 C 函数,这就是该规则未涵盖它的原因。

标签: c++ language-lawyer c++-standard-library reserved-words


【解决方案1】:

这个声明有两个部分,因为它谈到了保留的名称(来自 C 标准)(用于 C++ 实现)。特别是,

第 1 部分:声明的 C 标准库中的每个函数签名 与外部链接

这包括 C 库函数abs

第 2 部分:保留给实现以用作函数 带有 extern "C" 和 extern "C++" 链接的签名,或作为名称 全局命名空间中的命名空间范围。

所以名称::abs 是为C++ 实现保留的。你不能使用它。重载无关紧要。

【讨论】:

  • 如果这意味着名称::abs 是保留的,那么原始引用中的所有非粗体文本都是多余的。不是说你错了,但这段话似乎仍然有些神秘。
  • abs 不是函数签名,因此不能在第 1 部分中引用。
  • 出于某种原因,每个人都跳过了 p3:“使用外部链接声明的 C 标准库中的每个名称都保留给实现用作具有 extern "C" 链接的名称,在命名空间 std 和在全局命名空间中。”
  • @T.C.为什么这是相关的?我没有用 C 链接声明 abs
  • 该名称保留供全局命名空间(除其他外)中的实现使用。实现的用途无关紧要。
【解决方案2】:

tl;博士- 是的,你可以

http://www.eel.is/c++draft/reserved.names#extern.names

拉入上下文的其余部分:

20.5.4.3.2:如果程序在保留名称的上下文中声明或定义名称,除非本条款明确允许,否则其行为未定义。

还有

20.5.4.3.3.2 在标头中使用外部链接声明的每个全局函数签名都保留给实现,以指定具有外部链接的函数签名。

20.5.4.3.3.4 使用外部链接声明的 C 标准库中的每个函数签名都保留给实现,以用作具有 extern "C" 和 extern "C++" 链接的函数签名,182 或作为全局命名空间中的命名空间范围。

这些建议你可以,因为它只是保留的签名。

命名空间 ::std 的奖励

http://www.eel.is/c++draft/library#namespace.std

20.5.4.2.1.1 除非另有说明,否则如果 C++ 程序向命名空间 std 或命名空间 std 内的命名空间添加声明或定义,则其行为未定义。

http://en.cppreference.com/w/cpp/language/extending_std总结了异常

【讨论】:

  • 添加到namespace std没有问题,而是添加到全局命名空间。
  • @Walter 如果标准明确声明 std 不能扩展,但没有说明全局命名空间;并明确声明它是保留的函数签名 - 然后在全局命名空间中添加新的签名不会被标准拒绝......
  • 在这个论证中我们需要std 的部分吗?
  • @Walter 因为第一部分建议您也可以重载 std 中的任何函数 - 这是您不能的,我不希望这个答案表明您可以。
  • 这是一条红鲱鱼。这个问题显然与全局命名空间有关(仅)。
猜你喜欢
  • 2015-12-28
  • 2011-07-14
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多