切勿使用'#include“filename.h”'指令

时间:2015-05-27 06:35:22

标签: c++ c

我对[1]中的“AV规则33”有疑问。

它说“#include指令应使用<filename.h>表示法来包含头文件。”

该文件通过“供应商实施中的分歧”来“解释”它,但我有相信问题。 “本地标题”文件是本地头文件?!

编译器在“local”的定义中差异很大吗?

[1] http://www.stroustrup.com/JSF-AV-rules.pdf

3 个答案:

答案 0 :(得分:2)

看起来像一个奇怪的理由。至少在C中,任何一种形式都是特定于实现的。

C11 6.10.2和C ++ 03 16.2在这里似乎100%相同:

  

表单

的预处理指令      

# include <h-char-sequence> new-line

     

在一系列实现定义的地方搜索标题   通过&lt;之间的指定序列唯一地识别。和&gt;   分隔符,并导致整个指令的替换   标题的内容。如何指定地点或标题   确定是实现定义的。

     

预处理指令   表格

     

# include "q-char-sequence" new-line

     

导致由该标识的源文件的全部内容替换该指令   “分隔符”之间的指定序列。命名的源文件是   以实现定义的方式搜索。如果不支持此搜索,或者搜索   失败后,指令被重新处理,就像它读取

一样      

# include <h-char-sequence> new-line

     

具有与原始相同的包含序列(包括>字符,如果有的话)   指令。

正如我们可以在标准中读到的那样,两个表单都使用实现定义的搜索。标准显式表示如果#include "filename.h"失败,它将恢复为#include <filename.h>"。所以理由没有任何意义。

答案 1 :(得分:2)

我在10年前与一些编译器合作过,可能需要这种理由。我并不是说这是一个很好的理由,并试图捍卫它,但只是想澄清它为什么会出现。

基本上在我们的情况下,我们绊倒了,因为我们有一些本地项目标题(对于像插件这样的小项目),其命名的名称相当简洁,如rect.hmem.h。我们认为使用本地样式的include指令可以保护我们免受冲突,并且除了我们遇到的情况之外,它在大多数编译器上都有。

我不记得究竟哪个编译器绊倒了我们(我认为它是CodeWarrior的旧版本,但我的记忆可能让我失望)。无论如何,这个编译器正在处理:

#include "rect.h"

......同义词:

#include <rect.h>

基本上,前者包含的样式与rect.h与包含它的源文件完全相同的目录没有区别。它仍然按照它们出现在项目和编译器设置的指定包含路径中的顺序搜索头文件的优先级,因此我们在那里遇到了很多冲突,标准头文件和操作系统头文件我们几乎无法解决,除非命名头文件文件更好,更不一般,以较少冲突的方式。也许我们可以尝试一些其他的东西:

#include "./rect.h"

......或许这会奏效(虽然看起来有点傻)。我们也许可以尝试通过项目和编译器设置强制预处理器将项目自己的目录优先于所有其他包含路径。我们没有尝试用尽所有可能的解决方案,只是重新命名我们的头文件,我们一致地应用前缀约定,以避免冲突更简单,而不必逐案分析事情。

这是特别尴尬的,因为我们在我们控制之外的第三方库中获取它,并且更改此类代码非常严重(例如:我们可能需要使用新版本的库再次执行此操作)。

这就是我们所做的一切。我们实际上没有提出一个编码标准,建议避免使用前者包括仅支持使用后者的风格,但我可以看到为什么有人可能会根据类似的编译器问题确定这个理由。

问题在于,如果我们针对多个平台并使用各种编译器并且有时移植到新的编译器,我们不幸的是必须针对最低的公分母。如果最低公分母在#include "rect.h"#include <rect.h>之间没有区别,那么这两者不同的想法就会成为某些编译器的幻觉,而对其他编译器则是现实。

这种不一致可能会引起混淆,并且可能导致更少的移植头痛,只是简单地采用后一种风格来恢复一致性,或许更快速地实现,在远见而不是事后看到一堆尝试移植代码时构建错误,以较少的方式命名标题。

答案 2 :(得分:0)

pdf明确指出

  

然而,由于供应商实施中的不幸分歧,   只有&lt; filename.h&gt;表格将被使用。

他的意思是,为了包含供应商提供的文件,你不应该做“filename.h”,因为它只会在本地路径中搜索。