Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么是“;noexcept表达式的计算结果为‘;假’;因为打电话到…”;?_C++ - Fatal编程技术网

C++ 什么是“;noexcept表达式的计算结果为‘;假’;因为打电话到…”;?

C++ 什么是“;noexcept表达式的计算结果为‘;假’;因为打电话到…”;?,c++,C++,考虑以下示例: #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{}; } #包括 使用T=std::chrono::system\u clock::time\u point; 结构

考虑以下示例:

#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{};
}
#包括
使用T=std::chrono::system\u clock::time\u point;
结构A
{
A()=默认值;
显式A(T时间):时间{time}
{
}
T时间{};
};
阿福()
{
返回一个{};
}
当我使用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{};
      |            ^
$g++-c noexcept.cpp-o noexcept.cpp.o--std=c++17-Wnoexcept
noexcept.cpp:18:12:警告:noexcept表达式计算结果为“false”,因为调用了“constexpr std::chrono::time\u point::time\u point()[with _Clock=std::chrono:::_V2::system\u Clock;_Dur=std::chrono::duration]”[-Wnoexcept]
18 |返回{};
|            ^
我不明白这个警告的意思。它仅在第二个构造函数就位时生成(即使从未调用它)

警告涉及正在求值的noexcept表达式。因为我没有看到任何这样的表达式,所以我假设在第一个构造函数中有类似于隐式noexcept表达式的东西。但我不明白为什么那样的事情会导致警告。如果有第二个构造函数,为什么会有区别呢


你能解释一下这个代码的问题吗?

我觉得这是一个假阳性诊断。因为确实没有任何noexcept表达式会因为该函数而计算为false


另外,如果我从
A::time
中删除默认成员初始值设定项,则不会重现该行为。据我所知,这在示例程序中没有语义差异。

似乎您明确选择了
-Wnoexcept
。此处解释了标志的含义:

当noexcept表达式由于调用没有非抛出异常规范(即throw()或noexcept)但编译器已知从未抛出异常的函数而计算为false时发出警告

在这种情况下,我不得不猜测编译器正在隐式地计算一个包含
T{}
的noexcept表达式,以确定
a
的默认构造函数是否应该隐式声明
noexcept
。出现警告是因为编译器可以确定
time\u point
的默认构造函数从不抛出,但所述默认构造函数未声明为
noexcept
。看


您的代码没有问题。警告的根本原因是
time\u point
没有相应的
noexcept
声明。但是,对于许多标准库构造函数来说,这是正确的,修复所有这些构造函数需要很长时间。因此,与此同时,这一警告似乎主要增加了噪音。如果仍要使用此标志进行编译,可以将
A::A()
自己定义为
A()noexcept{}
。(在本例中,您不会放弃琐碎性,因为
t::t()
无论如何都不是琐碎的。)

除了默认构造函数之外,复制构造函数是否还默认或显式指定为
a(const a&a)noexcept:time(a.time){}
(带或不带noexcept)。据我理解,这两者之间应该没有区别。我是不是误解了什么,或者这是怎么发生的?@n314159同样的问题。如果复制构造函数是默认的,编译器将查看为成员和基选择的复制构造函数,以便计算隐式异常规范。啊,我想现在我明白了。只有当编译器必须猜测构造函数是否应为noexcept时,才会出现警告,因此,如果我告诉编译器构造函数是否应为noexcept,即使生成的代码应相同,也很重要。感谢您的解释!由于您提到的问题,我选择暂时禁用警告。