为什么此代码是非常量条件?
static_assert(4294965 * 1000 / 1000 == -2, "overflow occurs");
但这不是:
const int overflowed = 4294965 * 1000 / 1000;
static_assert(overflowed == -2, "overflow occurs");
请参阅Godbolt上的代码。注意:使用 gcc <9 秒的代码也有错误。
为什么此代码是非常量条件?
static_assert(4294965 * 1000 / 1000 == -2, "overflow occurs");
但这不是:
const int overflowed = 4294965 * 1000 / 1000;
static_assert(overflowed == -2, "overflow occurs");
请参阅Godbolt上的代码。注意:使用 gcc <9 秒的代码也有错误。
https://en.cppreference.com/w/cpp/language/constant_expression
核心常量表达式是其评估不会评估以下任何一项的任何表达式:
- [...]
- 一个表达式,其评估会导致任何形式的核心语言未定义行为(包括有符号整数溢出、被零除、数组边界外的指针算术等)。未指定是否检测到标准库未定义行为。
由于未指定是否gcc
会检测到未定义的行为,因此当它仅在某个时候检测到时,可能会导致一些奇怪的情况,例如您的情况
如果你改变你的const
,constexpr
你会得到同样的错误
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 适得其反的“聪明”编译器的技巧迟早都应该避免