1

为什么此代码是非常量条件?

static_assert(4294965 * 1000 / 1000 == -2, "overflow occurs");

但这不是:

const int overflowed = 4294965 * 1000 / 1000;
static_assert(overflowed == -2, "overflow occurs");

请参阅Godbolt上的代码。注意:使用 gcc <9 秒的代码也有错误。

4

1 回答 1

1

https://en.cppreference.com/w/cpp/language/constant_expression

核心常量表达式是其评估不会评估以下任何一项的任何表达式:

  • [...]
  • 一个表达式,其评估会导致任何形式的核心语言未定义行为(包括有符号整数溢出、被零除、数组边界外的指针算术等)。未指定是否检测到标准库未定义行为。

由于未指定是否gcc会检测到未定义的行为,因此当它仅在某个时候检测到时,可能会导致一些奇怪的情况,例如您的情况

如果你改变你的constconstexpr你会得到同样的错误

constexpr int overflowed = 4294965 * 1000 / 1000;

铿锵声似乎都失败了你的解决方案:https ://godbolt.org/z/qocG8xfzb


笔记:

即使您找到了解决static_assert未定义行为的方法并获得了您希望的结果,但这并不意味着您可以在程序的稍后部分期待相同的结果。

请参阅:https ://en.cppreference.com/w/cpp/language/ub

UB和优化

因为正确的 C++ 程序没有未定义的行为,所以当实际具有 UB 的程序在启用优化的情况下编译时,编译器可能会产生意想不到的结果

恕我直言,大多数试图用 UB 适得其反的“聪明”编译器的技巧迟早都应该避免

于 2021-06-17T08:00:11.840 回答