C与C++对于全局变量的不同处理之处

发表于:2012-2-07 10:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:sdtarena    来源:51Testing软件测试网采编

  下面看看我犯的错误:

  当时写了一个类似于下面的枚举:

#ifndef TEST_ENUM_H_
#define TEST_ENUM_H_
enum {
TEST_FLAG1_E,
TEST_FLAG2_E,
TEST_FLAG_NR
} TEST_E;
#endif

  当时在enum关键字前面遗漏了“typedef”。我一般习惯于使用typedef,这样可以直接使用TEST_E而不是enum TEST_E。

  该头文件会被其它源文件引用。由于在代码中,没有需要定义枚举变量的地方,只是使用枚举的值,所以当时没有发现遗漏“typedef”。编译也没有任何问题。

  但是当天的build却没有通过。错误信息显示定义了重复的TEST_E,因此编译失败。由于与美国的时差问题,这个错误由美国的一同事修改了。他陈述的错误原因是:这样的枚举声明对于C来说,是没有问题的。——我们的核心代码都是C编写的。

  但是对于C++,会认为不是声明而是定义,定义了一个TEST_E变量。结果导致重复定义了该变量。——有一部分web功能代码是使用C++编写的。

  当我早上看到他的说明时,首先要对break build表示歉意;第二也鄙视了一下该产品的makefile——我刚刚加入这个产品组。这样的makefile,为了检查checkin,我不得不先make clean才能保证所有的代码被编译。这样花费的时间太多了。第三,我才想起web的这部分功能是使用C++的。第四,寒一下自己,居然漏写了typedef;第五,也有些好奇C++的编译为什么出错。

  但是当我看到他的陈述时,我知道他肯定错了。对于C和C++来说,枚举enum的区别不会这么大。对于上面那个枚举类型定义,由于遗漏了typedef,所以这里的TEST_E无论是C还是C++来说,都会把TEST_E当作一个枚举变量处理,也就是一个全局变量。那么引起问题的原因是因为C和C++对于没有初始值的全局变量的处理不同——真拗口,而最后的编译链接行为不同。

  看下面的简单示例:

  文件test1.c

int a;
int main()
{
return 0;
}

  文件test2.c

int a;

  编译

[fgao@fgao-vm-fc13 test]$ gcc -g -Wall test1.c test2.c
[fgao@fgao-vm-fc13 test]$

  编译没有任何的warning和error。对于没有初始值的全局变量,其为弱符号。对于多个弱符号定义,在C的链接阶段不会有任何问题。

  在这篇文章中,我解释了为什么C允许多个弱符号存在

  下面将其视为C++代码,使用g++编译:

[fgao@fgao-vm-fc13 test]$ g++ -g -Wall test1.c test2.c
/tmp/ccQdTwRi.o:(。bss+0x0): multiple definition of `a'
/tmp/cc7SOWD1.o:/home/fgao/works/test/test1.c:4: first defined here
collect2: ld returned 1 exit status

  同样是没有初始值的全局变量,在C++的链接阶段就会报错。对于C++为什么报错,这肯定是由于C++的链接机制有关。目前我并不清楚原因,有了解的朋友请赐教。谢谢。

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号