知识点滴 - 关于头文件的重复包含问题

本文介绍了C/C++中使用Includeguard防止头文件重复包含的方法及其重要性。通过条件编译指令实现,避免重复定义导致的编译错误,提高开发效率。此外,对比了#ifndef与#pragmaonce两种方式的特点。

使用Include guard的目的

C Language Tutorial => Header Include Guards

2.12 — Header guards – Learn C++

C/C++中,#include,这个预处理命令会将此命令后面的文件内容包含进来。

而一般情况下,后面是一个头文件, 比如name.h,因为一般都在源文件的开头来包含,所以叫头文件。

头文件里面的内容其实没有严格限制,可以包含变量或函数的声明或定义,还有类型的定义,宏定义等。

而对一个源文件,.c或.cpp文件,处理完预处理指令,将头文件包含进来并替换宏定义后,得到的就一个可编译单元 - translation unit (TU)。

对于这个可编译单元来讲,是可以包含很多个头文件,头文件里还可以包含其他头文件,所以才会有一个头文件会被间接的多次包含的问题。

对于函数声明来说,如果一个编译单元里出现多次相同的声明没有问题,但如果是一个编译单元里对同一个对象(变量)或类型有多个定义,或者是同一个作用域里有重复定义,比如全局空间有重复定义,就会编译报错。

在C/C++中,一个类型只能定义一次,比如对相同的结构体类型定义只能出现一次,不能重复。

所以在包含头文件时,里面的内容都是一些类型定义,就不能重复包含。这也包括一些宏定义,也不能重复定义。

重复包含一个头文件,可能会导致编译错误,就算头文件中都是可以重复出现的声明之类的内容,多次包含的话,也会增加预处理器或编译器的工作量,增加软件构建的时间。

而一般情况下, 头文件中包含较多的内容都是forward declaration,前向声明,表示还没有给出完整的定义的标识符(表示编程的实体,如数据类型、变量、函数)。有了这个声明,编译的源文件就可以使用此标识符,而不需要关系其定义与否。在链接阶段,才会使用到具体的定义。

尤其在很大的项目中,头文件很多,其内容很长时,这会降低开发效率,增加开发成本。

为了解决重复包含头文件的问题,引入了header guard(或者叫include guard),来防止头文件的多次包含。

header guard使用条件编译指令,一种预处理指令。

在一个源文件中包含此头文件my_include.h时,会检查此宏定义是否定义,如果是第一次包含,没有定义,则下一步定义这个宏,并将后面的内容包含进来。

然后预处理器对此源文件继续操作,后面再出现包含此头文件时,因为这个宏已经定义,则后面内容不会包含进来。

注意,这里宏生效的范围仅在单个源文件内。

例如:

my_include.h

#ifndef SOME_UNIQUE_NAME_HERE

#define SOME_UNIQUE_NAME_HERE

// your declarations (and certain type

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜流冰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值