"noexcept-expression 由于对......的调用而计算为'假'"是什么意思?



请考虑以下示例:

#include <chrono>
using T = std::chrono::system_clock::time_point;
struct A
{
A() = default;
explicit A(T time) : time{time}
{
}
T time{};
};
A foo()
{
return A{};
}

当我使用 GCC 9.2.0 编译此代码时,它将生成以下警告:

$ g++ -c noexcept.cpp -o noexcept.cpp.o --std=c++17 -Wnoexcept
noexcept.cpp:18:12: warning: noexcept-expression evaluates to ‘false’ because of a call to ‘constexpr std::chrono::time_point<_Clock, _Dur>::time_point() [with _Clock = std::chrono::_V2::system_clock; _Dur = std::chrono::duration<long int, std::ratio<1, 1000000000> >]’ [-Wnoexcept]
18 |   return A{};
|            ^

我不明白这个警告的含义。它仅在第二个构造函数就位时生成(即使它从未被调用(。

该警告涉及正在评估的 noexcept-expression。由于我没有看到任何这样的表达式,我想在第一个构造函数中有一个隐含的 noexcept-expression 的东西。不过,我不明白为什么这样的事情会导致警告。如果第二个构造函数存在,为什么会有所不同?

您能否对此进行一些说明并解释此代码的问题是什么?

您似乎明确选择了-Wnoexcept.标志的含义解释如下:https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html

当 noexcept-expression 由于调用没有非抛出异常规范(即 throw(( 或 noexcept(但编译器知道永远不会抛出异常的函数而计算结果为 false 时发出警告。

在这种情况下,我必须猜测编译器正在隐式评估涉及T{}的noexcept表达式,以确定是否应将A的默认默认构造函数隐式声明为noexcept。出现警告是因为编译器可以确定time_point的默认构造函数永远不会抛出,但所述默认构造函数未声明noexcept。有关定义,请参阅此处。

您的代码没有问题。警告的根本原因是time_point没有适当的noexcept声明。但是,对于许多标准库构造函数来说都是如此,并且修复所有这些构造函数需要很长时间。因此,与此同时,此警告似乎主要增加了噪音。如果您仍想使用此标志进行编译,则可以将自己A::A()定义为A() noexcept {}。(在这种情况下,你不会放弃琐碎,因为无论如何T::T()都不是琐碎的。

这对我来说看起来像是一个误报诊断。因为确实没有任何 noexcept-expression 会因为该功能而计算为 false。

附言如果我从A::time中删除默认成员初始化器,则行为不会重现。据我所知,这在示例程序中没有语义差异。

相关内容

最新更新