首页 > 解决方案 > 声明中的 noexcept 不一致是否违反 ODR?

问题描述

这是一个两部分的问题,第一部分是关于完全用 C++ 编写的东西,第二部分是关于用 C 编写但从 C++ 调用的函数之间的交互。

第1部分

noexcept让不同的翻译单元在同一函数的声明中看到不同的说明符是 ODR 还是其他违规行为?具体来说,如果一个单位看到:

void foo();

而另一个人看到:

void foo() noexcept;

是 ODR 还是其他违规行为?您可能会假设该函数实际上从不抛出(即,它实际上可以被声明noexcept)。

第2部分

如果所有 C++ 代码都将声明视为extern "C" void foo() noexcept;,但该函数实际上是在 C 中定义(实现)的,而声明(显然)不包括noexcept?

标签: c++clanguage-lawyernoexceptone-definition-rule

解决方案


是 ODR ... 违规吗?

这不是 ODR 违规。这些:

void foo();
void foo() noexcept;

只是声明。它们不是定义,一个定义规则不限制它们。

这是......其他违规行为吗?

是的。它违反了以下规则(引用最新的标准草案):

[除了.spec]

如果函数的声明没有 noexcept 说明符,则该声明具有潜在的抛出异常规范,除非[exception that does not apply],在这种情况下,异常规范如下指定,并且该函数的其他声明不应具有一个 noexcept 说明符。...仅当单个翻译单元中的异常规范不同时,才需要进行诊断。


如果所有 C++ 代码都将声明视为 extern "C" void foo() noexcept;,但该函数实际上是在 C 中定义(实现)的,其中声明(显然)不包括 noexcept,是否违反?

技术上也许。但是 C++ 标准并不真正适用于 C,所以这可能是未指定的。noexcept即使该程序在技术上是错误的,如果一个 TU 认为一个函数只要该函数从不抛出,我不确定是否存在任何实际问题。

值得一提的是,glibcthrow()仅在包含在 C++ 中时才在使用 GCC 时声明标准 C 函数。


推荐阅读