为什么在包括警卫之前放置#include

时间:2014-04-07 09:11:33

标签: c++ include c-preprocessor spidermonkey

是否有任何正当理由将#include指令放在头文件中的包含警戒之前:

#include "jsarray.h"
#include "jsanalyze.h"
#include "jscompartment.h"
#include "jsgcmark.h"
#include "jsinfer.h"
#include "jsprf.h"
#include "vm/GlobalObject.h"

#include "vm/Stack-inl.h"

#ifndef jsinferinlines_h___
#define jsinferinlines_h___

//main body mostly inline functions 

#endif

请注意,此示例取自应由经验丰富的程序员开发的真实高调的开源项目 - Firefox 10中使用的Mozilla Spidermonkey开源Javascript引擎(相同的头文件也存在于最新版本中)

在备受瞩目的项目中,我预计其设计必须有一些正当理由。在包含警卫之前有#include的正当理由是什么?它是一种适用于仅内联函数头文件的模式吗?另请注意,此头文件(jsinferinlines.h)实际上是通过最后#include "vm/Stack-inl.h"(此头文件包含许多其他头文件,其中一个实际上包含此jsinferinlines.h)指令包含在内这对我来说更不合理。

2 个答案:

答案 0 :(得分:4)

因为你希望这些标题包含自己的守卫,所以它并没有什么区别。

  

另请注意,此头文件(jsinferinlines.h)实际上是通过最后一个#include“vm / Stack-inl.h”包含自身(此头文件包含许多其他头文件,其中一个实际上包含此jsinferinlines再次。在包含守卫之前的指令,这对我来说更不合理。

它不会有任何不同,因为包含该文件时的工作流程将是:

  • 包括最多"vm/Stack-inl.h"
  • 的所有标题
  • 包括"vm/Stack-inl.h"到最后#include "jsinferinlines.h"(您的文件)
  • 再次包含文件jsinferinlines.h(跳过所有以前的包含,因为包括警卫)
  • 到达#include "vm/Stack-inl.h"
  • 最后从#ifndef jsinferinlines_h___
  • 处理

但总的来说,相互标头递归是不好的,应该不惜一切代价避免。

答案 1 :(得分:1)

当时SpiderMonkey标头中有很多包含周期,并且将标题保护放在顶部导致难以理解编译错误 - 我怀疑将标题保护放在包含之下只是对清除包含的一个渐进步骤。

我无法告诉你导致它产生影响的包含的确切顺序。

现在SM标头中不应该包含任何包含循环,并且它们的样式是通过Nicholas Nethercote编写的python脚本强制执行的。如果你今天看看jsinferinlines.h,你会看到标题后卫位于它所属的顶部。