免费注册 查看新帖 |

Chinaunix

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

问高手一个数据段的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-18 16:27 |只看该作者 |倒序浏览
有4个文件:glo.h, b.h,b.c, a.c, 为了测试问题,在glo.h中定义(不是声明)一个全局变量
两个问题:
[1]b.c汇编后,b.c中定义的全局变量test_b_init位于.rodata段,test_b汇编后看不到,而glo.h中的global_var位于data段,为什么不一样?
[2]当glo.h中global_var没有初始化时,最终a.c可以编译执行,而如果global_var初始化,则报多次定义错误!这是为什么?



  1. //glo.h
  2. #ifndef _GLO_H_
  3. #define _GLO_H_

  4. int global_var=8;

  5. #endif
复制代码

//b.h
#ifndef _H_T_B_H
#define _H_T_B_T

void get_a();

#endif

  1. //b.c
  2. #include <stdio.h>

  3. #include "glo.h"

  4. int test_b;
  5. int test_b_init=1;

  6. void get_a()
  7. {
  8.         printf("b.c: a is :%d\n",global_var);
  9. }
复制代码




  1. //a.c
  2. #include <stdio.h>

  3. #include "glo.h"
  4. #include "b.h"


  5. int main()
  6. {
  7.         get_a();

  8.         printf("a.c: global_var is:%d\n",global_var);
  9.         return 0;
  10. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2008-08-18 16:54 |只看该作者
有没有知道的高手在?

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
3 [报告]
发表于 2008-08-18 17:04 |只看该作者
你这就在搞笑了,居然出了两个同一名字的全局变量,而且都有初值。

论坛徽章:
0
4 [报告]
发表于 2008-08-18 17:24 |只看该作者

回复 #3 cjaizss 的帖子

恩?两个变量一个名字?没有啊

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
5 [报告]
发表于 2008-08-18 22:41 |只看该作者

回复 #4 yifei429 的帖子

你觉得以下程序有问题吗?

  1. //b.c
  2. #include <stdio.h>
  3. int global_var=8;
  4. int test_b;
  5. int test_b_init=1;
  6. void get_a()
  7. {
  8.         printf("b.c: a is :%d\n",global_var);
  9. }
复制代码

  1. //a.c
  2. #include <stdio.h>
  3. int global_var=8;
  4. #include "b.h"


  5. int main()
  6. {
  7.         get_a();

  8.         printf("a.c: global_var is:%d\n",global_var);
  9.         return 0;
  10. }
复制代码

论坛徽章:
0
6 [报告]
发表于 2008-08-19 00:29 |只看该作者
[1]b.c汇编后,b.c中定义的全局变量test_b_init位于.rodata段,test_b汇编后看不到,而glo.h中的global_var位于data段,为什么不一样?

首先,test_b_init位于.data段,不是.rodata。第二,test_b位于.comm段(汇编代码中在.comm段,如果是二进制的代码,它在.bss段,而.bss段中的数据是不在可执行文件中出现的,因为它们都是0,只是在地址空间中给它们保留了一段,这就是你说的“看不到”吧)。

[2]当glo.h中global_var没有初始化时,最终a.c可以编译执行,而如果global_var初始化,则报多次定义错误!这是为什么?

这两个问题都涉及到同一个地方,全局声明怎么处理。

在一个文件中,如果你定义了一个全局变量,并且给了它显示的初始化表达式,那么这个变量会放到这个文件对应的汇编文件的.data段中,如果你没有给出显示的初始化表达式,那么这个变量会被放到.comm段中。
当链接器链接多个文件时,同名的.comm成员会被合并成一个。

现在可以回答你的第二个问题了。
当你没有给global_val初值时,a.o和b.o中各有一个global_var的定义(都没有初值),但是它们目前并没有存储空间,定义在.comm段中。当链接器将a.o和b.o链接起来的时候,发现.comm中同名的global_var,会将这两个变量合并起来,作为一个变量,在.bss段中分配空间。当你在程序中引用global_var的时候,其实引用的都是同一个地方。
如果global_var有初值,那么在a.o和b.o的.data段中各有一个全局的global_var。链接器会告诉你重复定义。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2008-08-19 09:36 |只看该作者
写C语言程序的时候,永远不要在头文件下定义全局变量
漏写了“全局”两个字,补上;
因为头文件的包含可能会导致全局变量重复定义

[ 本帖最后由 cjaizss 于 2008-8-19 13:32 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2008-08-19 12:34 |只看该作者
顶Alex和版主,最近学习《C和指针》,被作用域搞得晕乎乎的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP