仍然不确定c++中的有符号整数溢出



在下面的代码中,我测试了哪种形式的溢出会导致UB,以及导致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。

更奇怪的是,标准说++xx += 1是一样的,但是使用它在gcc(和clang)上没有更多的错误。

进一步x += 1应与x = x + 1相同,因此rhs被提升为int,结果被隐式转换。所以,这应该是新的UB。

所以,问题是,这三个语句中的哪一个真的应该是UB(我认为只有++x),哪个编译器是正确的?

[expr.pre.incr]/1

表达式++x等价于x+=1。

[expr.ass]/6

E1 op= E2形式的表达式的行为等价于E1 = E1 op E2,只是E1只求值一次。

但是x = x + 1不是UB(整数提升和窄化整数转换),所以原来是格式良好的。因此,GCC是错误的。

最新更新