Bee*_*ope 3 c c++ one-definition-rule language-lawyer noexcept
这是一个两部分的问题,第一部分是关于完全用 C++ 编写的东西,第二部分是关于用 C 编写但从 C++ 调用的函数之间的交互。
让不同的翻译单元noexcept在同一函数的声明中看到不同的说明符是 ODR 还是其他违规行为?具体来说,如果一个单位看到:
void foo();
Run Code Online (Sandbox Code Playgroud)
而另一个人看到:
void foo() noexcept;
Run Code Online (Sandbox Code Playgroud)
这是 ODR 还是其他违规行为?您可能会假设该函数实际上永远不会抛出(即,它实际上可以被声明noexcept)。
如果所有 C++ 代码都将声明视为extern "C" void foo() noexcept;,但该函数实际上是在 C 中定义(实现)的,其中声明(显然)不包含noexcept?
这是 ODR ... 违规吗?
这不是 ODR 违规。这些:
Run Code Online (Sandbox Code Playgroud)void foo(); void foo() noexcept;
只是声明。它们不是定义,一个定义规则并不限制它们。
这是……其他违规行为吗?
是的。它违反了以下规则(引自最新的标准草案):
[除.spec]
如果函数的声明没有 noexcept 说明符,则该声明具有潜在的抛出异常规范,除非[不适用的异常],在这种情况下,异常规范如下所述,并且该函数的其他声明不应具有一个 noexcept 说明符。... 仅当单个翻译单元中的异常规范不相同时才需要诊断。
如果所有 C++ 代码都将声明视为 extern "C" void foo() noexcept;,但该函数实际上是在 C 中定义(实现)的,其中声明(显然)不包含 noexcept,是否违反?
技术上也许。但是 C++ 标准并不真正适用于 C,所以这可能是指定不足的。即使程序在技术上格式错误,如果一个 TU 认为一个函数noexcept只要该函数从不抛出,我也不确定是否存在任何实际问题。
值得一提的是,glibcthrow()仅在包含到 C++ 中时才在使用 GCC 时声明标准 C 函数。