【问题标题】:Include directive can match two files: what's the priority?include 指令可以匹配两个文件:优先级是什么?
【发布时间】:2020-08-05 11:16:28
【问题描述】:

当有两个具有相同指定名称的文件时,首选哪个文件:第一个在包含它的文件所在的目录中,第二个在其他地方但它的目录在包含路径中?

例如:(proj_dir 在包含路径中)

.
└── proj_dir
    ├── a
    │   ├── a.c -> #include "b.h"
    │   └── b.h
    └── b.h

a 也在包含路径中时有什么变化吗?

【问题讨论】:

  • 预处理器搜索#included 文件的位置由实现定义。通常,#include "b.h" 会首先在当前目录中搜索,但标准并不要求这样做。对于大多数编译器,有一些选项(例如包含路径、环境变量)会影响所发生的事情。您需要阅读编译器的文档才能 100% 确定。或者测试它——在"b.h" 的两个版本中做一些明显不同的事情(比如每个版本定义一个不同的宏,然后检查a.c。定义了哪个宏)。
  • 优先级取决于编译器,因为它是实现定义的。你用的是什么编译器?

标签: c++ c header include include-path


【解决方案1】:

当使用双引号 " 包含文件时,预处理器将首先在与执行包含的文件相同的目录中查找。

在你的情况下,如果文件proj_dir/a/a.c 有:

#include "b.h"

那么它将包含proj_dir/a/b.h 文件。

如果在同一目录中没有找到文件,则预处理器将查看包含路径。


如果包含使用尖括号<>,那么预处理器将首先在包含路径中查找。

还要注意,预处理器会按照指定的顺序查看每个包含路径,并停止查看第一个命中。因此,如果您的包含文件位于多个包含路径中,则只会包含找到的第一个文件。因此,添加搜索路径的顺序很重要。


虽然此行为确实是实现定义的(如评论中所述),但主要实现的一般行为与此相差不大。

唯一的偏差实际上是如何添加系统包含路径。 MSVC(例如)有多个选项来添加包含路径,并且它们按特定顺序搜索。虽然 GCC 有一个预先配置的系统目录列表,但会首先搜索。

但是对于双引号包含的行为,所有的实现都会优先使用当前文件的目录。

【讨论】:

  • 我想它在标准中。您能否提供对标准中适当条款的引用(C 或 C++,因为 C++ 肯定会继承 C 的规则)?
  • @AdlerAmorette 我没有直接可用的规范参考,但请参阅this #include directive reference
  • @AdlerAmorette Could you provide a reference to 在标准中,它都是“实现定义的”。 port70.net/~nsz/c/c11/n1570.html#6.10.2p3
  • 这个答案指的是“包含路径”,而没有先说明它们是什么。对于尚未熟悉这些概念的人来说,对未定义术语的暗示常常会让人感到困惑。首先解释概念会更清楚,通常,编译器在文件系统中有一个路径列表,它在其中搜索包含在#include "name" 中的文件,并在其中搜索包含在#include <name> 中的文件的路径列表,并且这些列表通常可以通过编译器开关进行配置(并且在构建/安装编译器时使用默认值)等等。
  • @RobertSsupportsMonicaCellio,假设一个人的想法是非常粗鲁的。事实上,你得出了一个错误的结论。
猜你喜欢
  • 2010-09-28
  • 2013-08-05
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 2014-08-11
相关资源
最近更新 更多