C++ g++;严格溢出、优化和警告

C++ g++;严格溢出、优化和警告,c++,warnings,integer-overflow,C++,Warnings,Integer Overflow,当使用strict overflow标志编译以下代码时,在第二次测试中,它告诉我r可能不是我认为的那样: int32_t r(my_rand()); if(r < 0) { r = -r; if(r < 0) { // <-- error on this line r = 0; } } 编辑:我删除了我的第一个答案,因为它无效。这是一个全新的版本。感谢@Neil Kirk指出我

当使用strict overflow标志编译以下代码时,在第二次测试中,它告诉我r可能不是我认为的那样:

    int32_t r(my_rand());
    if(r < 0) {
        r = -r;
        if(r < 0) {   // <-- error on this line
            r = 0;
        }
    }

编辑:我删除了我的第一个答案,因为它无效。这是一个全新的版本。感谢@Neil Kirk指出我的错误

问题的答案如下:

GCC总是假设,签名溢出永远不会发生,并且在这个假设下,它(总是)优化内部
if(r<0)


如果您打开
-Wstrict overflow
,编译器会发现
r=-r
r<0
之后可能仍然是真的(如果
r==-2^31
),这会导致错误(错误是由基于从不发生溢出的假设的优化引起的,而不是溢出可能性本身-这就是
-Wstrict overflow
的工作原理)。

r=-2147483648
时,什么是
-r
?有符号整数的范围是不对称的:从-2147483648到2147483647。因此,将-2147483648与0进行比较(在CPU/汇编语言级别实现为减法、0-(-2147483648)和检查符号标志)将导致溢出。如果
r=-2147483648
,那么
-r=0
。这不是溢出吗?你是对的。我目前正在重写我的答案。感谢你发现了这一点,它最终让我得到了有效的答案。这很有趣,因为我想抓住这个案例“并修复它”(在我的具体案例中,是使用0)但这更清楚。
/build/buildd/libqtcassandra-0.5.5/tests/cassandra_value.cpp:
     In function 'int main(int, char**)':
/build/buildd/libqtcassandra-0.5.5/tests/cassandra_value.cpp:2341:13:
     error: assuming signed overflow does not occur when simplifying
     conditional to constant [-Werror=strict-overflow]
         if(r < 0) {
         ^
    r = -r;