如何防止gcc优化器产生不正确的位操作? [英] How can I prevent the gcc optimizer from producing incorrect bit operations?
问题描述
请考虑以下程序。
#include <stdio.h>
int negative(int A) {
return (A & 0x80000000) != 0;
}
int divide(int A, int B) {
printf("A = %d\n", A);
printf("negative(A) = %d\n", negative(A));
if (negative(A)) {
A = ~A + 1;
printf("A = %d\n", A);
printf("negative(A) = %d\n", negative(A));
}
if (A < B) return 0;
return 1;
}
int main(){
divide(-2147483648, -1);
}
如果在没有编译器优化的情况下进行编译,则会产生预期的结果。
When it is compiled without compiler optimizations, it produces expected results.
gcc -Wall -Werror -g -o TestNegative TestNegative.c
./TestNegative
A = -2147483648
negative(A) = 1
A = -2147483648
negative(A) = 1
使用编译器优化进行编译时,会产生以下错误输出。
When it is compiled with compiler optimizations, it produces the following incorrect output.
gcc -O3 -Wall -Werror -g -o TestNegative TestNegative.c
./TestNegative
A = -2147483648
negative(A) = 1
A = -2147483648
negative(A) = 0
我正在运行 gcc版本5.4.0
。
我是否可以在源代码中进行更改,以防止编译器在 -O3下产生此行为?
?
Is there a change I can make in the source code to prevent the compiler from producing this behavior under -O3
?
推荐答案
-
-2147483648
并没有执行您认为的操作。 C没有负常数。包含limits.h
并使用INT_MIN
代替(几乎每个INT_MIN
在二进制补码机上的定义将其定义为(-INT_MAX-1)
是有原因的。)
-2147483648
does not do what you think it does. C doesn't have negative constants. Includelimits.h
and useINT_MIN
instead (pretty much everyINT_MIN
definition on two's complement machines defines it as(-INT_MAX - 1)
for a good reason).
A =〜A + 1;
调用未定义的行为,因为〜A + 1
导致整数溢出。
A = ~A + 1;
invokes undefined behavior because ~A + 1
causes integer overflow.
不是编译器,而是您的代码。
It's not the compiler, it's your code.
这篇关于如何防止gcc优化器产生不正确的位操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!