LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 755|回复: 4

gcc加-O与否出现不同的结果,谁的错误??

[复制链接]
发表于 2009-5-11 09:19:52 | 显示全部楼层 |阅读模式
我写了这样一个程序:
#include <stdio.h>

int main()
{
   const int a=2;
   int *p;

   p=&a;
   printf("%d,a=%d\n",*p,a);

   (*p)++;
   printf("%d.a=%d\n",*p,a);

   return 0;
}

用     gcc -Wall -o t1 t1.c
编译后,结果为:
2,a=2
3,a=3

然而用 gcc -Wall -O -o t1 t1.c
编译后,结果确为:
2,a=2
3,a=2

请问一下,这倒底是谁的错呀?
 楼主| 发表于 2009-5-11 09:26:19 | 显示全部楼层
第二个错误是:

#include <stdio.h>

int *t(void)
{
    int i=3;
    return &i;
}

int main(void)
{
    int *p;
    int i;
   
    for(i=0; i<3; i++)
    {
        p=t();
        printf("%d\n",*p);
    }
    return 0;
}


用 gcc -Wall -o t1 t1.c
编译后,结果为:
3
3
3

然而用 gcc -Wall -O -o t1 t1.c
编译后,结果确为:
2507256
1
2

请问一下,这倒底是谁的错呢?
回复 支持 反对

使用道具 举报

发表于 2009-5-12 22:58:47 | 显示全部楼层
Post by cczy;1985866
我写了这样一个程序:
#include <stdio.h>

int main()
{
   const int a=2;
   int *p;

   p=&a;
   printf("%d,a=%d\n",*p,a);

   (*p)++;
   printf("%d.a=%d\n",*p,a);

   return 0;
}

用     gcc -Wall -o t1 t1.c
编译后,结果为:
2,a=2
3,a=3

然而用 gcc -Wall -O -o t1 t1.c
编译后,结果确为:
2,a=2
3,a=2

请问一下,这倒底是谁的错呀?
  1. p=&a;
复制代码

编译器应该告诉你这句有问题了吧
回复 支持 反对

使用道具 举报

发表于 2009-5-12 23:02:24 | 显示全部楼层
Post by cczy;1985869
第二个错误是:

#include <stdio.h>

int *t(void)
{
    int i=3;
    return &i;
}

int main(void)
{
    int *p;
    int i;
   
    for(i=0; i<3; i++)
    {
        p=t();
        printf("%d\n",*p);
    }
    return 0;
}


用 gcc -Wall -o t1 t1.c
编译后,结果为:
3
3
3

然而用 gcc -Wall -O -o t1 t1.c
编译后,结果确为:
2507256
1
2

请问一下,这倒底是谁的错呢?

  1. return &i;
复制代码

编译器应该告诉你这句有问题了吧,你返回了一个局部变量的地址,理论上它是不可知的!可以在定义前面加static来解决。
回复 支持 反对

使用道具 举报

发表于 2009-5-13 10:37:02 | 显示全部楼层
第一个问题我遇到过

const 类型的变量,gcc在编译时会直接定义为一个常量

也就是说,这句

printf("%d.a=%d\n",*p,a);

直接在编译阶段就被翻译成

printf("%d.a=%d\n",*p,2);


所以无论对p指针做什么操作,都不会影响a的值
感兴趣的话可以用objdump反汇编看一下

第二个问题嘛,逻辑上就有问题

t函数返回后,变量i就被销毁了,第一次能取得正确的结果页只是碰巧而已。

这么写程序的话,调试的时候碰到SIGSEGV是你运气好,否则在程序里埋下隐患,关键时刻出错就闯祸了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表