免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2737 | 回复: 10
打印 上一主题 下一主题

gcc 4.1不同的编译参数怎么会给出不同的结果? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-29 18:48 |只看该作者 |倒序浏览
以下求最无符号数的最左边的1是哪一位的程序,没想到不同的编译参数给出不同的结果;我程序写得有什么问题吗?

filename: highbits.c

  1. #include<stdio.h>

  2. int highbits(unsigned int j);

  3. int main()
  4. {
  5.         int ii,n;
  6.         unsigned int i = 0x45000000;
  7.         for(ii=0; ii < 100000000; ii++)
  8.                 n = highbits(i);      
  9.         printf("%d\n",n);
  10.       
  11. }


  12. int highbits(unsigned int j){
  13.         float f = j;
  14.         unsigned int* p = (unsigned int*)(&f);
  15.         int offset = ( ( *p & 0x7f800000) >> 23 ) - 127;
  16.         return offset;
  17. }
复制代码

用不同的优化参数编译得到的结果让人费解:
方法1:

  1. ifree@MMMIX ~/test $ gcc highbits.c -o highbits
  2. ifree@MMMIX ~/test $ time ./highbits
  3. 30

  4. real    0m1.505s
  5. user    0m1.504s
  6. sys     0m0.000s
复制代码

方法2:

  1. ifree@MMMIX ~/test $ gcc -O1 highbits.c -o highbitsO1
  2. ifree@MMMIX ~/test $ time ./highbitsO1
  3. 30

  4. real    0m0.002s
  5. user    0m0.000s
  6. sys     0m0.004s
复制代码

速度快了何止万倍????

方法3:

  1. ifree@MMMIX ~/test $ time ./highbitsO2
  2. -127

  3. real    0m0.002s
  4. user    0m0.000s
  5. sys     0m0.004s
复制代码

竟然得到错误的结果

方法4:

  1. ifree@MMMIX ~/test $ gcc -O3 highbits.c -o highbitsO3
  2. ifree@MMMIX ~/test $ time ./highbitsO3
  3. -127

  4. real    0m0.109s
  5. user    0m0.104s
  6. sys     0m0.004s
复制代码

速度不快反慢

论坛徽章:
0
2 [报告]
发表于 2006-05-07 21:48 |只看该作者
unsigned int* p = (unsigned int*)(&f);

浮点类型跟整型这样转化是错误的.
你把float j的定义改为unsigned j就OK了

论坛徽章:
0
3 [报告]
发表于 2006-05-08 09:56 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
4 [报告]
发表于 2006-05-08 11:19 |只看该作者
原帖由 oke 于 2006-5-7 21:48 发表
unsigned int* p = (unsigned int*)(&f);

浮点类型跟整型这样转化是错误的.
你把float j的定义改为unsigned j就OK了

浮点数可以写成 unsigned float j;吗?
如果我那样写是错误的,为什么不加优化参数编译得到的是正确的结果呢?

论坛徽章:
0
5 [报告]
发表于 2006-05-08 11:25 |只看该作者
我能说是gcc4.1的bug吗?

原来我没有gcc 3.4.6,今天编译了一个gcc 3.4.6,重新编译这个程序,加上优化参数没有问题了。怪事!

论坛徽章:
0
6 [报告]
发表于 2006-05-09 15:01 |只看该作者
浮点类型的编码格式跟整型的类型完全不一样.
你这样强制转化
unsigned int* p = (unsigned int*)(&f);

gcc是探测不到这样的错误的,本身错误的语义在不同的优化选项下是有可能产生不同的结果的.
所以这不能算gcc的bug.

----
以下是个小程序,看下输出结果,你就知道是否是你所要的.

#include <stdio.h>


int main(int argc, char *argv[])
{
  float f =1;
  unsigned int* p = (unsigned int*)(&f);
  printf("*p %d\n",*p);
}

论坛徽章:
0
7 [报告]
发表于 2006-05-09 22:44 |只看该作者
>> 我能说是gcc4.1的bug吗?
>> 原来我没有gcc 3.4.6,今天编译了一个gcc 3.4.6,重新编译这个程序,加上优化参数没有问题了。怪事!

这已经充分说明是 gcc 4.1 的 bug。建议提交这个 bug。

oke 在上面说 unsigned int* p = (unsigned int*)(&f); 这里的强制转化存在语义错误,这是不成立的。因为这不是一个标准未定义的行为。oke 之所以说存在语义错误可能是还没有理解这样做的意义。

论坛徽章:
0
8 [报告]
发表于 2006-05-10 11:03 |只看该作者
我记得 gcc 手册上好像说过,使用优化后有可能造成程序不正常...

论坛徽章:
0
9 [报告]
发表于 2006-05-10 21:59 |只看该作者
>> 我记得 gcc 手册上好像说过,使用优化后有可能造成程序不正常...

编译器无论对程序进行怎样的优化,必须要保证运行结果的正确性。否则优化是没有意义的。

你说的使用优化后有可能造成程序不正常可能指的是程序调试不正常,这是允许的。

论坛徽章:
0
10 [报告]
发表于 2006-05-10 22:45 |只看该作者
执行 gcc hightbits.c -S -O4
得到 hightbits.s

  1.         .file        "hightbits.c"
  2.         .text
  3.         .p2align 4,,15
  4. .globl highbits
  5.         .type        highbits, @function
  6. highbits:
  7. .LFB13:
  8.         movl        -4(%rsp), %eax
  9.         andl        $2139095040, %eax
  10.         shrl        $23, %eax
  11.         subl        $127, %eax
  12.         ret
  13. .LFE13:
  14.         .size        highbits, .-highbits
  15.         .section        .rodata.str1.1,"aMS",@progbits,1
  16. .LC1:
  17.         .string        "%d\n"
  18.         .text
  19.         .p2align 4,,15
  20. .globl main
  21.         .type        main, @function
  22. main:
  23. .LFB12:
  24.         movl        -4(%rsp), %eax
  25.         movl        $100000000, %edx
  26.         andl        $2139095040, %eax
  27.         shrl        $23, %eax
  28.         leal        -127(%rax), %esi
  29.         .p2align 4,,7
  30. .L6:
  31.         decl        %edx
  32.         jne        .L6
  33.         movl        $.LC1, %edi
  34.         xorl        %eax, %eax
  35.         movl        $0x4e8a0000, -4(%rsp)
  36.         jmp        printf
  37. .LFE12:
  38.         .size        main, .-main
  39.         .section        .eh_frame,"a",@progbits
  40. ......
复制代码

[ 本帖最后由 x2 于 2006-5-11 16:04 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP