全局变量的定义,以及如何处理头文件包含关系

看到博客里面都不推荐将全局变量定义到.h文件中,表示很困惑,加上一开始就对文件包含关系不是很理解,所以今天通过查找资料和测试力争将问题搞懂。

首先测试#ifndef #define #endif 在头文件编译中到底能够起到什么作用能?1.能够控制整个工程对于该头文件的包含,也就是说对于添加了#ifndef #define #endif

的头文件一个工程只会包含一次该头文件。2.只能控制一个.c文件只包含这个头文件一次。下面我们定义一个testGlobal.h文件和两个包含该.h文件的.cpp文件,testGlobal.cpp和

testGlobal2.cpp内容如下:

testGlobal.h

#ifndef TESTGLOBAL_H
#define TESTGLOBAL_H

int GlobalCount;

#endif


testGlobal.cpp

#include "testGlobal.h"

testGlobal2.cpp

#include "testGlobal.h"
#include <iostream>
void main()
{
     std::cout<<GlobalCount<<std::endl;
}
此时编译器会提示,redefined这说明两个C文件中都直接包含了头文件的内容。

接下来我们分析#ifndef #define #endif在防止一个C文件将同一个头文件包含两次的作用。这里重新定义一个文件testGlobal2.h

#ifndef TESTGLOBAL2_H
#define TESTGLOBAL2_H
#include "testGlobal.h"
int GlobalCount2 = 5;
#endif
将testGlobal.h和testGlobal2.h都包含到testGlobal.cpp中,并清除testGlobal2.cpp,此时可以顺利编译。可见#ifndef的声明只对一个.cpp文件而言。


基于上述问题,一般在使用全局变量时,都将全局变量定义到某一个.cpp文件中,在.h文件使用extern从而避免出现重定义的问题。

对于.h文件中的宏定义是有编译器直接替换为常值的,不会编译到.obj文件中,所以不会出现重复定义。同时也可以在.h文件中定义结构体,枚举因为这些都是由

有编译器处理,直接在编译时候替换的,所以也不会报错。


实际上有关全局变量重定义的问题在《深入理解计算机系统》一书中有叙述:链接器在解析全局符号时,会遵循以下原则:

1.不允许有多个强符号

2.强弱符号都有选强

3.多个弱符号,任选其中一个

强符号是指:函数和已初始化的全局变量;成员函数如果定义在类外面,那么是强符号;模板函数的特化版本是强的;

弱符号是指:未初始化的全局变量;成员函数如果定义在类里面,那么是弱符号;模板类中的成员函数无论定义在类内还是类外,都是弱类型;模板函数是弱类型;

实际上强弱符号判断是可能出现问题的。因为编译器实际操作的全局变量可能并不是你希望的,可能造成错误。

如果想在全局变量重复定义就发出警告的话,对于GCC可以添加GCC-warn-common选项。通过我的测试在CCS的c编译器上面,在同一个.c文件中重复定义变量

不会报错编译器是按照强弱符号进行判断的,但是要是在不同文件中定义了相同的变量就会报错。而使用g++编译的C++程序,后缀.cpp上述两种情况都会报错,通不

过编译。

通过以上分析,在定义全局变量不应该定义在.h文件中。




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值