使用严格溢出标志编译以下内容时,它告诉我,在第二次测试时,r可能不是我认为的那样:
int32_t r(my_rand());
if(r < 0) {
r = -r;
if(r < 0) { // <-- error on this line
r = 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;
答案 0 :(得分:3)
编辑:我删除了第一个答案,因为它无效。这是全新的版本。感谢@Neil Kirk指出我的错误。
问题的答案在这里:https://stackoverflow.com/a/18521660/2468549
GCC总是假设,签名溢出永远不会发生,并且在此假设下,它(始终)优化内部if (r < 0)
块。
如果您打开-Wstrict-overflow
,编译器会发现r = -r
r < 0
可能仍然为真(如果最初为r == -2^31
),这会导致错误(错误是基于溢出假设从不发生的优化引起的,而不是溢出可能性本身 - 这就是-Wstrict-overflow
的工作方式。