为什么会在项目中使用#include_next?

引用Wrapper Headers上的iOS 文档 :

#include_next不区分<file>和“file”包含,也不检查指定的文件是否与当前文件具有相同的名称。 它只是查找名为的文件,从find当前文件的目录之后的searchpath中的目录开始。

使用`#include_next'会导致很大的混淆。 我们build议只在没有其他select的情况下使用它。 特别是,不应该在属于特定程序的头文件中使用; 它应该只用于沿着fixincludes的方向进行全局更正。

那么,两个问题,#include_next是什么,为什么你需要使用它?

如果你想用自己的默认头文件replace默认头文件,例如,假设你想replace“stdlib.h”。 你会在你的项目中创build一个名为stdlib.h的文件,而不是默认的头文件。

#include_next用于如果你想添加一些东西到stdlib.h而不是完全replace它。 您创build一个名为stdlib.h的新文件,其中包含:

 #include_next "stdlib.h" int mystdlibfunc(); 

编译器不会再recursion地包含你的 stdlib.h,就像平常一个#include那样,而是在其他目录中继续一个名为“stdlib.h”的文件。

如果你支持多个版本的东西,这很方便。 例如,我正在编写支持PostgreSQL 9.4和9.6的代码。 存在一些内部的API变化,大部分是现有function的新参数。

兼容性头文件和包装函数

我可以用static inline包装函数来编写兼容性头文件,其中包含所有东西的新名称,基本上是一个包装API,我在代码中使用包装名称。 用下面的语句说something_compat.h

 #include "something.h" static inline something* get_something_compat(int thingid, bool missing_ok) { assert(!missing_ok); return get_something(thingid); } 

但是在任何地方分散_compat或任何后缀是很难_compat

包装头

相反,当针对旧版本构build时,我可以在包含path中插入兼容性头文件,例如compat94/something.h

  #include_next "something.h" #define get_something(thingid, missing_ok) \ ( \ assert(!missing_ok), \ get_something(thingid) \ ) 

所以其余的代码可以使用9.6签名。 当针对9.4构build时,我们将前缀-Icompat94作为头部searchpath。

需要小心,以防止多重评估,但如果你使用#include_next你显然不介意依靠gcc。 在这种情况下,你也可以使用语句expression式 。

当新版本是“主要”目标时,这种方法很方便,但是在某些有限的时间段内需要向旧版本的后向兼容。 因此,您逐渐弃用旧版本,并尝试通过参考当前版本来保持代码清洁。

备择scheme

或者做一个明智的人,使用C ++,并使用重载函数和模板内联函数: