免费注册 查看新帖 |

Chinaunix

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

世界真奇妙,这个也会出错。。 [复制链接]

论坛徽章:
0
51 [报告]
发表于 2008-09-25 10:24 |只看该作者
为试了一下,为什么在VC2005上没有发现大家所说的错误呢, 也没有warning infomation!

论坛徽章:
0
52 [报告]
发表于 2008-09-25 10:25 |只看该作者
原帖由 Godbach 于 2008-9-25 09:17 发表


为什么t1在main之前已经初始化了,main里面再去赋值呢?

只是测试一下,这两种方法都是正确的,仅仅测试语法

论坛徽章:
0
53 [报告]
发表于 2008-09-25 11:05 |只看该作者

回复 #51 liu1061 的帖子

当年VC里连void main()都算对呢。
编译器不报错并不意味着代码没问题。一切以ANSI C/C++为准

论坛徽章:
0
54 [报告]
发表于 2008-09-25 11:40 |只看该作者
怎么感觉50#的解释一塌糊涂啊
具有静态存储区的变量只在程序运行期间有效 他只可以在程序运行前被初始化一次
第一条 由于本例中结构体是具有静态存储区的,所以他必须以常量和字符串形式初始化  p为指针显然是变量  &a不同 为常量地址值
如果p值做了改变会与第一条的初始化一次冲突
   
还请 emacsnw  指正

论坛徽章:
0
55 [报告]
发表于 2008-09-25 12:34 |只看该作者
原帖由 tyc611 于 2008-9-24 18:34 发表
构造体的{}形式的初始化表达式只能是常量表达式,不能是变量(你的p是变量),所以不能通过编译

誰說的?

论坛徽章:
0
56 [报告]
发表于 2008-09-25 14:35 |只看该作者

从汇编语言的角度看待const

struct T{
char *name;
int * id;
}

struct T t1 { "fuck", &a };

  gcc编译如上代码的汇编代码如下:

.globl t1
        .section        .rodata
.LC0:
        .string        "fuck"
        .data
        .align    4
        .type        t1, @object
        .size        t1, 8
t1:
        .long           .LC0
        .long           a
        .section        .rodata

  从as的角度,a是const,因为as能直接引用a的地址。但是如果初始化时写做p,那么这里引用的
就应该是p的值。但是这里是对全局变量t1的定义,而非statement,从汇编语言定义的角度是错误的。

struct T t1 { "fuck", p};
如果采用g++编译,其汇编代码如下:
.globl t1
        .section        .rodata
.LC0:
        .string        "kk"
        .data
        .align 4
        .type        t1, @object
        .size        t1, 8
t1:
        .long        .LC0
        .zero        4

  最后的.zero指示as用0填充4个byte,这说明as不能在编译时能设置t1.id。而实际上,g++额外生成了如下的
代码来完成对t1的最终初始化:
.globl __gxx_personality_v0
        .align 2
        .type        _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB3:
        pushl        %ebp
.LCFI5:
        movl        %esp, %ebp
.LCFI6:
        subl        $8, %esp
.LCFI7:
        movl        %eax, -4(%ebp)
        movl        %edx, -8(%ebp)
        cmpl        $1, -4(%ebp)
        jne        .L7
        cmpl        $65535, -8(%ebp)
        jne        .L7
        movl        p, %eax
        movl        %eax, t1+4

.L7:
        leave
        ret
.LFE3:
        .size        _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii

如上语句的movl %eas, t1+4就是对t1.id的初始化,而这个函数会在启动main之前被调用,所以在进入main之后,t1.id已经
被设置为p的值了,即&a。

论坛徽章:
0
57 [报告]
发表于 2008-09-25 14:39 |只看该作者
好笑啊

论坛徽章:
0
58 [报告]
发表于 2008-09-26 00:33 |只看该作者
int a;
int *p=&a;

全局变量初始化有什么特别的顺序吗

论坛徽章:
0
59 [报告]
发表于 2008-09-26 01:23 |只看该作者
原帖由 yu_xm 于 2008-9-25 08:33 发表
int a;
int *p=&a;

全局变量初始化有什么特别的顺序吗


全局变量的初始化在同一个编译单元是保证顺序的,但是不同编译单元的全局变量,谁先被初始化是不确定的。
所以 a.c 里面定义 int a = 10;
b.c里面 extern int a; int b = a + 1;
这样子是错误的,b不一定能被初始化为 11,因为a的初始化不一定在b前面。

论坛徽章:
0
60 [报告]
发表于 2008-09-26 08:52 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP