全局变量可不可以定义在可被多个.c文件包含的头文件中

问题:
全局变量可不可以定义在可被多个.c文件包含的头文件中?

引自《游戏引擎架构》:
链接规范,每个C/C++的定义都有名为链接规范(linkage)的属性。外部链接(external linkage)的定义可被定义处以外的翻译单元看见并引用。内部链接(internal linkage)的定义则只能被该定义所处的翻译单元看见,而不能被其他翻译单元引用。我们称此属性为链接规范,因为它觉得链接器是否容许该实体做交叉引用。因此,在某种意义上,链接规范类似C++ pulibc:/private:关键字在定义类时的作用,不过其作用对象不是类而是翻译单元。
所有定义预设为外部链接。使用static关键字可以把定义改为内部链接。
从技术上来说,声明不会有链接属性,因为声明不会在可执行映像中分配存储空间;因此,不存在链接器是否容许交叉引用那些存储空间的问题。

理解:
(所谓的)全局变量global定义在头文件中,因为所有定义预设为外部链接,所以在头文件被.c文件包含以后,等于有两个或更多同等定义的global存在于不同的翻译单元,编译器发现不了错误,因为编译器每次是以翻译单元运作的。但是,链接器会在解析交叉引用时报告“符号被多重定义”错误。

//DefineGlobal.h
int global;

//GlobalTest1.c
#include "DefineGlobal.h"

//GlobalTest2.c
#include "DefineGlobal.h"

E:\cpp\牛客网>g++ -std=c++11 DefineGlobal.h GlobalTest1.c GlobalTest2.c
C:\Users\\AppData\Local\Temp\ccseJhV1.o:GlobalTest2.c:(.bss+0x0): multiple definition of `global'
C:\Users\\AppData\Local\Temp\cccqfbA0.o:GlobalTest1.c:(.bss+0x0): first defined here

当把(所谓的)全局变量global定义为static时,由于static使定义的变量称为内部链接,所以在各个.c文件中,存在多个同名global但不同等的定义,每个翻译单元中的global维持自己的内存区域,此时链接器不会报告“符号被多重定义”错误。

//DefineGlobal.h
#ifndef DEFINEGLOBAL_H
#define DEFINEGLOBAL_H

static int global;

#endif

//GlobalTest1.c
#include <iostream>
#include "DefineGlobal.h"

void print1()
{
    global = 1;
    std::cout<<"print1 : "<<global<<std::endl;
}

//GlobalTest2.c
#include <iostream>
#include "DefineGlobal.h"


void print2()
{
    std::cout<<"print2 : "<<global<<std::endl;
    global = 2;
    std::cout<<"print2 : "<<global<<std::endl;

}

//GlobalMain.c
extern void print1();
extern void print2();

int main()
{
    print1();
    print2();

    return 0;
}

//输出
print1 : 1
print2 : 0
print2 : 2

此时,(所谓的)全局变量并没有达到一般意义上全局变量的效果,相当于每个翻译单元的局部变量。

结论:
全局变量不能定义在被多个.c文件包含的头文件中
————————————————
版权声明:本文为CSDN博主「basstal」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/basstal/article/details/52275191

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值