#include防范
在C和C++编程语言中,#include防范,有时被称作宏防范,用于处理#include
指令时,可避免重复引入的问题。在头文件加入#include防范是一种让文件等幂的方法。
重复引入
以下的C语言程序展示了缺少#include防范时会出现的问题:
- 文件“grandfather.h”
struct foo {
int member;
};
- 文件“father.h”
#include "grandfather.h"
- 文件“child.c”
#include "grandfather.h"
#include "father.h"
此处child.c间接引入了两份grandfather.h头文件中的内容。明显可以看出,foo
结构被定义两次,因此会造成编译错误。
使用#include防范
- 文件“grandfather.h”
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
struct foo {
int member;
};
#endif
- 文件“father.h”
#include "grandfather.h"
- 文件“child.c”
#include "grandfather.h"
#include "father.h"
此处grandfather.h第一次被引入时会定义宏GRANDPARENT_H。当father.h再次引入grandfather.h时,#ifndef
测试失败,编译器会直接跳到#endif
的部分,也避免了第二次定义foo
结构。程序也就能够正常编译。
困难
为了让#include防范正确运作,每个防范都必须检验并且有条件地设置不同的前置处理宏。因此,使用了#include防范的方案必须制订一致性的命名方法,并确定这个方法不会和其他的头文件或任何可见的全局变量冲突。
为了解决这个问题,许多C和C++程序开发工具提供非标准的指令#pragma once
。在头文件中加入这个指令,能够保证这个文件只会被引入一次。不过这个方法会被潜在性显著的困难阻挠,无论#include
指令是否在不同的地方,但实际上起源于相同的开头(举例,请参考符号链接)。同样的,因为#pragma once
不是一个标准的指令,它的语义在不同的程序开发工具中也许会有微妙的不同。