自动重复标头排除的一个困难是C标准在包含文件名的含义方面相对沉默。例如,假设正在编译的主文件包含#include "f1.h"
和#include "f2.h"
,为这些伪指令找到的文件都包含#include "f3.h"
。如果f1.h
和f2.h
处于不同目录中,但是通过搜索包含路径找到了,则不清楚#include
那些文件中的指令旨在加载同一f3.h
文件还是不同文件。
如果增加包含相对路径的包含文件的可能性,情况将变得更加糟糕。在某些情况下,头文件对嵌套include指令使用相对路径,并且希望避免对提供的头文件进行任何更改,在某些情况下,可能需要在项目目录结构中的多个位置重复头文件。即使存在该头文件的多个物理副本,也应在语义上将它们视为单个文件。
如果该#pragma once
指令允许标识符遵循once
,并且如果标识符与先前遇到的#pragma once
指令中的标识符匹配,则编译器应跳过该文件的语义,那么语义将是明确的;否则,语义将是明确的。一种可以告诉您#include
指令将加载与#pragma once
早期指令相同的带有标签的文件的编译器,通过跳过该文件而不再次打开它可以节省一些时间,但是这种检测在语义上并不重要,因为将跳过该文件是否文件名是否被识别为匹配项。但是,我不知道有任何编译器以这种方式工作。有一个编译器观察文件是否与模式匹配#ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing following
和处理这样的事情是等同于上面#pragma once someIdentifier
,如果someIdentifier
保持定义,本质上是一样的。
#pragma once
一个告诉编译器仅包含该文件一次。