免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: koolcoy
打印 上一主题 下一主题

求助: 在if中定义的变量 [复制链接]

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
71 [报告]
发表于 2007-08-13 19:13 |只看该作者

#include<stdio.h>

int main(void)
{
        char* p_a;

        {
                char a[10240]="1234567890abcdef";
                p_a=a;
        }

        printf("%s\n",p_a);

        return 0;
}


我用ICC GCC编译上述程序能输出1234567890abcdef
VC7.1什么也不输出

论坛徽章:
0
72 [报告]
发表于 2007-08-13 20:38 |只看该作者
原帖由 whyglinux 于 2007-5-23 20:38 发表

首先,i 是一个自动变量,所以它的存储空间是自动分配的,而不是动态分配的(当然,也不是静态分配的)。

其次,你问的这个问题涉及到具体实现,而对同一段程序可能有多种实现方式,所以很难给出一个准确的答案。另外,“在物理上存在”的具体含义也值得商榷。

自动变量一般对应着进程的栈空间。在具体实现中多以函数为单位使用栈,也就是说:在编译的时候已经根据自动变量的数量和类型确定出了函数需要的栈空间,并确定了变量在此空间中的相对地址(或相对偏移)。这样,当程序执行到函数的时候,函数使用的栈空间已经被保留,相应地,自动变量的地址被确定。从这个意义上来说,似乎我们可以说这个变量在执行到函数的时候物理上已经存在了。

自动变量对应的栈空间也可能被同一函数中定义在不同块中的变量使用,所以物理上存在不意味着逻辑上也存在。
如果程序以块为单位组织栈,是不是我们就可以说只有进入变量作用域之后在物理上才存在?

自动变量 i 也有可能被编译器设置为寄存器变量。寄存器是始终存在的,那么这个自动变量什么时候在物理上存在?是进入作用域的时候、进入函数的时候、程序开始执行的时候、甚至程序尚未执行就已经存在了?


这句话没有明白什么意思。作者可以给解释一下什么情况会有这种情况呢?是比如
  1. int
  2. example(void)
  3. {
  4.    if (1) {
  5.     int x;
  6.    }
  7.    if (1) {
  8.      int x;
  9.    }
  10.    if (1) {
  11.      int x;
  12.    }
  13. }    这样的形式?
复制代码
我印象里,所见到的编译器 gcc,xlc,HP-UX上的c编译器,编译出来,x都不会用同一个地址。不知道原作者这句话具体体现的例子
可能是什么样子的。

论坛徽章:
0
73 [报告]
发表于 2007-08-13 23:45 |只看该作者
同意看汇编代码来解释。

可是楼上给出的代码怎么解释?既然楼上说编译通过,那么x的生存期是?在x定义的前后的{}之间吗?如果生存期在{}之间,那么x何来在example被调用的时候分配x?如果生存期不在{}之间,那么,如何区分三个x?如果加上一句 x++;  又如何?

我这里没有编译器,谁给出汇编代码看看?

论坛徽章:
0
74 [报告]
发表于 2007-08-14 00:08 |只看该作者
原帖由 mik 于 2007-5-20 17:10 发表


他已经说得很明白了.

这是你说的:

若是这样子,你会怎么生成代码? 目前的编译器恐怕都无法做得到


我也觉得这样没法写编译器~~
实在想不出那样编译后的程序汇编是怎样的……

论坛徽章:
0
75 [报告]
发表于 2007-08-14 09:50 |只看该作者
存在。在VC里执行下面代码,观察任务管理器,证明buf是分配了的。


#include<stdio.h>
#include<conio.h>

int main()
{
        printf("test test test.\n");
        if(0)
        {
                int  buf[102400];
                printf("test2 test2 test2.\n");
        }
        _getch();
        return 0;
}

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
76 [报告]
发表于 2007-08-14 10:27 |只看该作者
归根结底就是函数压栈之后语句块是否再次单独压栈的问题

论坛徽章:
0
77 [报告]
发表于 2007-08-14 12:54 |只看该作者
显然
if(...) {
  int x;
}
里x的生存周期和
{
  int x;
  ...
}
是一样的

论坛徽章:
0
78 [报告]
发表于 2007-08-14 13:43 |只看该作者
原帖由 prc 于 2007-8-14 12:54 发表
显然
if(...) {
  int x;
}
里x的生存周期和
{
  int x;
  ...
}
是一样的


其实这里还有个编译器优化的问题,很可能第一种根本就不会分配空间,具体就看编译器如何实现了。

PS:一些看似简单的问题在CU往往都会变得异常复杂,汗一个~

论坛徽章:
0
79 [报告]
发表于 2007-08-14 13:45 |只看该作者
楼主情况,很有可能经过编译器优化后i是不被分配甚至不存在的,当然,还是看编译器如何实现的

论坛徽章:
0
80 [报告]
发表于 2007-08-14 16:05 |只看该作者
帖子续了好长.......... 没有耐心看完.......
只想说几点 说的不对 见谅

1. 个人认为汇编的代码还是比较说明问题的  同意思一科同学的看法 至少我试的结果是这样 下面是VC 6的代码 (手边暂时没有gcc 目前至少说明 gcc 和VC的编译器情况是一样的

if(0)  //有同学谈到判断条件可能会影响变量分配 这样应该不会作到了吧

je          main+2Bh (0040103b)
  {
183:          int i[20] ;
184:          i[2] = 9;
00401034   mov         dword ptr [ebp-48h],9
185:      }
186:
187:      int a = 10;
0040103B   mov         dword ptr [ebp-54h],0Ah   //这里很明显把i的空间预留出来了
188:
至于其他编译器 不知道.........

2. 思一科同学说的在理 但是有点咄咄逼人的味道  阁下大牛  但是建议态度还是平和一些好~

学习了 谢谢~  

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP