C和C++对待全局对象的一个不同之处

  今天阅读《深度探索C++对象模型》,得知在C之中,未初始化的全局对象“被视为一个‘临时性的定义’,因为它没有明确的初始化操作。一个‘临时性的定义’可以在程序中发生多次,那些实例会被链接器折叠起来,只留下单独一个实体”(见第197页)。于是我做了做实验,以验证书上说的话。

 

  我定义了两个c文件,分别是test1.c:

 

#include <stdio.h>

int a;

extern void foo();

int main()
{
    a = 1;
    foo();
    printf("%d\n", a);
}

 

  和test2.c:

 

int a;

void foo()
{
    a = 2;
}


 

  我采用Visual Studio C++ 2010的命令行提示符,用c语言模式分别对这两个文件进行编译,再将产生的两个obj文件链接,没有遇到任何错误:

 

>cl /TC /c test1.c
>cl /TC /c test2.c
>link /out:test.exe test1.obj test2.obj

 

  执行test.exe,输出结果是2,可见test1.c和test2.c中的变量a是同一个实例。

 

  而《深度探索C++对象模型》又提到:“C++并不支持‘临时性的定义’,这是因为class构造行为的隐含应用之故……global在C++中被视为完全定义(它会阻止第二个或更多个定义)……C++的所有全局对象都被当作‘初始化过的数据’来对待。”(还是见第197页)。

 

  因此我将test1.c改名为test1.cpp,将test2.c改名为test2.cpp,用c++模式分别对这两个文件进行编译,再将产生的两个obj文件链接。此时就遇到了链接错误:

 

>cl /EHsc /c test1.cpp
>cl /EHsc /c test2.cpp
>link /out:test.exe test1.obj test2.obj
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

test2.obj : error LNK2005: "int a" (?a@@3HA) already defined in test1.obj
test.exe : fatal error LNK1169: one or more multiply defined symbols found

 

  看来书中的话果然没错。

 

  不过需要注意的是,这些话只对未初始化的全局对象有效。举个例子,如果在test1.c中将int a;改为int a = 1;,在test2.c中将int a;改为int a = 2;,那么test1.obj和test2.obj的链接也会出现重定义错误。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值