#include防范

CC++编程语言中,#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不是一个标准的指令,它的语义在不同的程序开发工具中也许会有微妙的不同。

参考文献

外部链接