y***d 发帖数: 2330 | 1 发现下面这个程序 gcc 在不同的优化条件下给出不同的结果,看起来是个 gcc 的 bug;
gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
#include
int f(unsigned int x)
{
return ((x>>31)||((0-x)>>31));
//*(2*(x>>31) + 1);
}
int main()
{
printf("%d\n", f(1));
printf("%d\n", f(0));
printf("%d\n", f(-1));
return 0;
}
不优化时,
gcc 1.c -Wall
./a.out
1
0
1
优化时,
gcc 1.c -Wall -O
./a.out
1
1
1 |
N***m 发帖数: 4460 | 2 这个优化是可能出不一样的结果,我以前遇到过。
bug;
【在 y***d 的大作中提到】 : 发现下面这个程序 gcc 在不同的优化条件下给出不同的结果,看起来是个 gcc 的 bug; : gcc -v : Using built-in specs. : Target: x86_64-linux-gnu : gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) : #include : int f(unsigned int x) : { : return ((x>>31)||((0-x)>>31)); : //*(2*(x>>31) + 1);
|
y***d 发帖数: 2330 | 3 这说明这个优化是不对的,优化怎么也得同样结果才优化吧...
【在 N***m 的大作中提到】 : 这个优化是可能出不一样的结果,我以前遇到过。 : : bug;
|
y***d 发帖数: 2330 | 4 太狠了, gcc 是这么优化的:
f:
.LFB22:
.cfi_startproc
movl $1, %eax
ret
.cfi_endproc
【在 y***d 的大作中提到】 : 这说明这个优化是不对的,优化怎么也得同样结果才优化吧...
|
f*******y 发帖数: 55 | 5 问题出在 unsigned int x上吧。想想,-x || x 可不就是1么?它又不知道signed int
的范围是多少。 |
t****t 发帖数: 6806 | 6 looks really like a bug. send a bug report?
bug;
【在 y***d 的大作中提到】 : 发现下面这个程序 gcc 在不同的优化条件下给出不同的结果,看起来是个 gcc 的 bug; : gcc -v : Using built-in specs. : Target: x86_64-linux-gnu : gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) : #include : int f(unsigned int x) : { : return ((x>>31)||((0-x)>>31)); : //*(2*(x>>31) + 1);
|
t****t 发帖数: 6806 | 7 why? if x==0 then (-x || x)==false of course.
int
【在 f*******y 的大作中提到】 : 问题出在 unsigned int x上吧。想想,-x || x 可不就是1么?它又不知道signed int : 的范围是多少。
|
X****r 发帖数: 3557 | 8 看起来是个gcc bug。我试了试,把||换成|就没问题,
把(0-x)换成(unsigned int)(0-(int)x)和没问题,甚至把31换成30都对。
bug;
【在 y***d 的大作中提到】 : 发现下面这个程序 gcc 在不同的优化条件下给出不同的结果,看起来是个 gcc 的 bug; : gcc -v : Using built-in specs. : Target: x86_64-linux-gnu : gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) : #include : int f(unsigned int x) : { : return ((x>>31)||((0-x)>>31)); : //*(2*(x>>31) + 1);
|
N***m 发帖数: 4460 | 9 不清楚。我搞数值计算的,这样的情形遇到过几次,一般跟优化级别有关。
因为毕竟是优化,有可能优化错了,所以没觉得是bug。
不然的话,岂不是缺省就用optimization算了。
【在 y***d 的大作中提到】 : 这说明这个优化是不对的,优化怎么也得同样结果才优化吧...
|
y***d 发帖数: 2330 | 10 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45262
confirmed as a regression since 4.4
【在 t****t 的大作中提到】 : looks really like a bug. send a bug report? : : bug;
|
|
|
a****d 发帖数: 114 | 11 把0换成 0L 也没有问题 ..
【在 X****r 的大作中提到】 : 看起来是个gcc bug。我试了试,把||换成|就没问题, : 把(0-x)换成(unsigned int)(0-(int)x)和没问题,甚至把31换成30都对。 : : bug;
|
f*******y 发帖数: 55 | 12 看来是个bug。这个是和有符号整数的表示有关的。应该是作者没有考虑机型。
见 http://en.wikipedia.org/wiki/Signed_number_representations
0: 00000000 (+0) and 11111111 (−0)
vs
INT_MAX and (-INT_MAX -1)
还有C99规定 INT_MIN = -INT_MAX
gcc&vc 的limits.h 中却定义 INT_MIN 为 -INT_MAX -1.
怎么都觉得这个是个大坑。曾经在mips的SOC上栽过一次。 这个作为bug fix后,要回
头再查查原来的程序了。 |
y***d 发帖数: 2330 | 13 可能是这样
【在 f*******y 的大作中提到】 : 看来是个bug。这个是和有符号整数的表示有关的。应该是作者没有考虑机型。 : 见 http://en.wikipedia.org/wiki/Signed_number_representations : 0: 00000000 (+0) and 11111111 (−0) : vs : INT_MAX and (-INT_MAX -1) : 还有C99规定 INT_MIN = -INT_MAX : gcc&vc 的limits.h 中却定义 INT_MIN 为 -INT_MAX -1. : 怎么都觉得这个是个大坑。曾经在mips的SOC上栽过一次。 这个作为bug fix后,要回 : 头再查查原来的程序了。
|
l******e 发帖数: 12192 | 14 good to know
【在 f*******y 的大作中提到】 : 看来是个bug。这个是和有符号整数的表示有关的。应该是作者没有考虑机型。 : 见 http://en.wikipedia.org/wiki/Signed_number_representations : 0: 00000000 (+0) and 11111111 (−0) : vs : INT_MAX and (-INT_MAX -1) : 还有C99规定 INT_MIN = -INT_MAX : gcc&vc 的limits.h 中却定义 INT_MIN 为 -INT_MAX -1. : 怎么都觉得这个是个大坑。曾经在mips的SOC上栽过一次。 这个作为bug fix后,要回 : 头再查查原来的程序了。
|
f*****Q 发帖数: 1912 | 15 LLVM编译的结果(带优化)
int f(unsigned int x)
{
return ((x>>31)||((0-x)>>31));
//*(2*(x>>31) + 1);
}
define i32 @f(i32 %x) nounwind readnone {
entry:
ret i32 1
}
嘿嘿。 |
y***d 发帖数: 2330 | 16 怎么这 bug 都一样的?哦,好像 llvm 也是用的 gcc
【在 f*****Q 的大作中提到】 : LLVM编译的结果(带优化) : int f(unsigned int x) : { : return ((x>>31)||((0-x)>>31)); : //*(2*(x>>31) + 1); : } : define i32 @f(i32 %x) nounwind readnone { : entry: : ret i32 1 : }
|
s******n 发帖数: 876 | 17 Fermat's Last Theorem disproved by compiler optimizers:
http://blog.regehr.org/archives/140 |
D*********s 发帖数: 555 | 18 用clang试试
【在 y***d 的大作中提到】 : 怎么这 bug 都一样的?哦,好像 llvm 也是用的 gcc
|
p****o 发帖数: 1340 | 19
Yes!
这个定义应该对的吧?要不然有一个位置就浪费了。。。
【在 f*******y 的大作中提到】 : 看来是个bug。这个是和有符号整数的表示有关的。应该是作者没有考虑机型。 : 见 http://en.wikipedia.org/wiki/Signed_number_representations : 0: 00000000 (+0) and 11111111 (−0) : vs : INT_MAX and (-INT_MAX -1) : 还有C99规定 INT_MIN = -INT_MAX : gcc&vc 的limits.h 中却定义 INT_MIN 为 -INT_MAX -1. : 怎么都觉得这个是个大坑。曾经在mips的SOC上栽过一次。 这个作为bug fix后,要回 : 头再查查原来的程序了。
|
p****o 发帖数: 1340 | 20
才看了一下C99的定义,INT_MIN和INT_MAX的值正好相反。不过在前面一点也说了,具
体的实现必须同号,但可以在magnitude比他们大。所以gcc和VC是符合C99定义的。
【在 f*******y 的大作中提到】 : 看来是个bug。这个是和有符号整数的表示有关的。应该是作者没有考虑机型。 : 见 http://en.wikipedia.org/wiki/Signed_number_representations : 0: 00000000 (+0) and 11111111 (−0) : vs : INT_MAX and (-INT_MAX -1) : 还有C99规定 INT_MIN = -INT_MAX : gcc&vc 的limits.h 中却定义 INT_MIN 为 -INT_MAX -1. : 怎么都觉得这个是个大坑。曾经在mips的SOC上栽过一次。 这个作为bug fix后,要回 : 头再查查原来的程序了。
|
|
|
k*******d 发帖数: 701 | 21 贴一章书上的内容
18.6. Optimization
GCC can apply many techniques to make the executable program that it
generates faster and/or smaller. These techniques all tend to reduce still
further the "word-for-word" correspondence between the C program you write
and the machine code that the computer reads. As a result, they can make
debugging more difficult, and are usually applied only after a program has
been tested and debugged without optimization .
There are two kinds of optimization options. You can a |
t****t 发帖数: 6806 | 22 你想说什么呢?
【在 k*******d 的大作中提到】 : 贴一章书上的内容 : 18.6. Optimization : GCC can apply many techniques to make the executable program that it : generates faster and/or smaller. These techniques all tend to reduce still : further the "word-for-word" correspondence between the C program you write : and the machine code that the computer reads. As a result, they can make : debugging more difficult, and are usually applied only after a program has : been tested and debugged without optimization . : There are two kinds of optimization options. You can a
|
k*******d 发帖数: 701 | 23
就是想给大家提供点书上关于优化的内容而已
没啥,要是觉得没用就可以不看,或者碍眼我就删了就是了
【在 t****t 的大作中提到】 : 你想说什么呢?
|