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

参考文献

外部链接