仍然不确定 C++ 中的有符号整数溢出
Still unsure about signed integer overflow in C++
在下面的代码中,我测试了哪种形式的溢出会导致 UB 并因此导致
constexpr
上下文中的硬错误:
#include <cstdint>
#include <limits>
using T = int8_t;
int main() {
constexpr bool b = []{
T x = std::numeric_limits<T>::max();
++x; // GCC: UB, Clang: no UB
// x += 1;
// x = x + 1;
return (x > std::numeric_limits<T>::max());
}();
return b;
}
预增量给出了 gcc 的错误(如我所料),但不是 clang。
更奇怪的是,标准说 ++x
与 x += 1
相同,但使用它在 gcc(和以前的 clang)上不再出现错误。
并且进一步x += 1
应该和x = x + 1
一样,所以rhs被提升为int
并且结果被隐式转换。所以,这应该是较新的 UB。
所以,问题是,这三个语句中哪一个真的应该是 UB(我认为只有 ++x
),哪个编译器是正确的?
The expression ++x is equivalent to x+=1.
The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
但是x = x + 1
不是UB(整数提升和收缩整数转换),所以原来是well-formed。所以,GCC是错误的。
在下面的代码中,我测试了哪种形式的溢出会导致 UB 并因此导致
constexpr
上下文中的硬错误:
#include <cstdint>
#include <limits>
using T = int8_t;
int main() {
constexpr bool b = []{
T x = std::numeric_limits<T>::max();
++x; // GCC: UB, Clang: no UB
// x += 1;
// x = x + 1;
return (x > std::numeric_limits<T>::max());
}();
return b;
}
预增量给出了 gcc 的错误(如我所料),但不是 clang。
更奇怪的是,标准说 ++x
与 x += 1
相同,但使用它在 gcc(和以前的 clang)上不再出现错误。
并且进一步x += 1
应该和x = x + 1
一样,所以rhs被提升为int
并且结果被隐式转换。所以,这应该是较新的 UB。
所以,问题是,这三个语句中哪一个真的应该是 UB(我认为只有 ++x
),哪个编译器是正确的?
The expression ++x is equivalent to x+=1.
The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
但是x = x + 1
不是UB(整数提升和收缩整数转换),所以原来是well-formed。所以,GCC是错误的。