免费注册 查看新帖 |

Chinaunix

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

使用make时发现的一个值得小心的问题(新鲜出炉)!!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-03-10 16:57 |只看该作者 |倒序浏览
这个问题是我刚刚在工作中碰到的。
比如下列小程序:

  1. /******************************************/
  2. #include <stdio.h>;

  3. static char *head;

  4. void change(char *);
  5. /******************************************/
  6. int
  7. main(void)
  8. {
  9.         char name[] = "XiongBin Xiong.\n";
  10.         char *p;

  11.         p = name;
  12.         head = p;

  13.         printf("main()_1:%s",head);

  14.         change(p);

  15.         printf("main()_2:%s",head);

  16.         exit(0);
  17. }
  18. /********************************************/
  19. void
  20. change(char *ptr)
  21. {
  22.         char *q;

  23.         q = ptr;
  24.         q = q + 5;
  25.         head = q;

  26.         printf("change():%s",head);
  27. }
  28. /*******************************************/
复制代码

就一个文件,直接gcc编译,运行,输出结果为:
main()_1:XiongBin Xiong.
change():Bin Xiong.
main()_2:Bin Xiong.
当按照文中标示分为3个文件ourh.h,main.c,change.c使用make进行编译,运行,输出结果为:
main()_1:XiongBin Xiong.
change():Bin Xiong.
main()_2:XiongBin Xiong.
两者输出结果是不一样的。
我现在的认为是,程序段分开编译时,对于一个函数中全局变量的改变不能引起其他函数中该变量的值的变化。但到底里头是怎么一回事,到底有什么规则呢?我还不知道/。
有待学习。请各位高手指点。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2005-03-10 17:23 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

分开编译能编译过去吗?那个head可是static的。

论坛徽章:
0
3 [报告]
发表于 2005-03-10 17:44 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

能编译过!!

论坛徽章:
0
4 [报告]
发表于 2005-03-10 19:54 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

结果很好解释。因为在头文件中包含是的head的定义,所以当两个.c文件分别包含ourh.h时,结果实际上是定义了两个head。在编译后用nm可以看到二进制可执行文件中有两个head符号。

  1. bash-2.05b$ nm a.out
  2. 080496b4 A __bss_start
  3. 08048314 t call_gmon_start
  4. 08048440 T change
  5. 080496b4 b completed.1
  6. 08049688 d __CTOR_END__
  7. 08049684 d __CTOR_LIST__
  8. 080495b0 D __data_start
  9. 080495b0 W data_start
  10. 08048520 t __do_global_ctors_aux
  11. 08048340 t __do_global_dtors_aux
  12. 080495b4 D __dso_handle
  13. 08049690 d __DTOR_END__
  14. 0804968c d __DTOR_LIST__
  15. 080495bc D _DYNAMIC
  16. 080496b4 A _edata
  17. 080496c0 A _end
  18.          U exit@@GLIBC_2.0
  19. 08048550 T _fini
  20. 080495b0 A __fini_array_end
  21. 080495b0 A __fini_array_start
  22. 0804856c R _fp_hw
  23. 08048380 t frame_dummy
  24. 080485ac r __FRAME_END__
  25. 08049698 D _GLOBAL_OFFSET_TABLE_
  26.          w __gmon_start__
  27. 080496b8 b head
  28. 080496bc b head
  29. 0804850e T __i686.get_pc_thunk.bx
  30. 08048294 T _init
  31. 080495b0 A __init_array_end
  32. 080495b0 A __init_array_start
  33. 08048570 R _IO_stdin_used
  34. 08049694 d __JCR_END__
  35. 08049694 d __JCR_LIST__
  36.          w _Jv_RegisterClasses
  37. 080484bc T __libc_csu_fini
  38. 08048474 T __libc_csu_init
  39.          U __libc_start_main@@GLIBC_2.0
  40. 080483b4 T main
  41. 080495b8 d p.0
  42.          U printf@@GLIBC_2.0
  43. 080482f0 T _start
复制代码

由于这两个head的名称相同的,我们可以根据包含它们的源程序分别用head.main和head.change表示。在change.c程序中改变只是包含在这个程序中的head.change的值。没有改变head.main的值。出现这样的结果一点也不奇怪。

论坛徽章:
0
5 [报告]
发表于 2005-03-10 20:00 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!


  1. #include <stdio.h>;

  2. static char *head;

  3. void change(char *);
  4. /******************************************/
  5. int
  6. main(void)
  7. {
  8.        char name[] = "XiongBin Xiong.\n";
  9.        char *p;

  10.        p = name;
  11.        head = p;

  12.        printf("main()_1:%s",head);

  13.        change(p);

  14.        printf("main()_2:%s",head);

  15.        exit(0);
  16. }
  17. /********************************************/
  18. void
  19. change(char *ptr)
  20. {
  21.        char *q;

  22.        q = ptr;
  23.        q = q + 5;
  24.        head = q;

  25.        printf("change():%s",head);
  26. }
复制代码

这段代码反映楼主对static变量的理解不到位。看看change中的这一句:

  1. head = q;
复制代码

static变量是全局的,在main中赋值后,在change中就可以直接引用。不需要多此一举的。如果把这一句给注释掉,再来分开编译,你会change的输出结果为空。这也正是说明在main.c中和在change.c中定义的是两个不同的head。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2005-03-10 20:33 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

[quote]原帖由 "xxbview"]能编译过!![/quote 发表:


那个head是static的,照你上面的注释分开三个文件的话,我就不信能编译通过!

就是报定位不到head。

论坛徽章:
0
7 [报告]
发表于 2005-03-10 20:36 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

原帖由 "aero" 发表:


那个head是static的,照你上面的注释分开三个文件的话,我就不信能编译通过!

就是报定位不到head。

他是把第一部分做成头文件ourh.h。这样编译自然不成问题。
把第一部分当成.c文件是不行的。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
8 [报告]
发表于 2005-03-10 20:42 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

原帖由 "kj501" 发表:

他是把第一部分做成头文件ourh.h。这样编译自然不成问题。
把第一部分当成.c文件是不行的。


^_^,他又没说哦。只是放了注释在上面。

总之就是head找不到的问题啦。

论坛徽章:
0
9 [报告]
发表于 2005-03-10 20:45 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

他说了,就是这句话:

  1. 当按照文中标示分为3个文件ourh.h,main.c,change.c使用make进行编译,运行,输出结果为:
复制代码

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
10 [报告]
发表于 2005-03-10 20:47 |只看该作者

使用make时发现的一个值得小心的问题(新鲜出炉)!!!

[quote]原帖由 "kj501"][/quote 发表:


啊呀,丢脸死了,暴汗       

        

谁再提,偶把这帖子删了。       
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP