【发布时间】:2015-09-15 22:55:03
【问题描述】:
当我将-I 选项与gcc/clang 一起使用时,预处理器是进行递归向下搜索还是仅搜索给定目录?我找到了this,但它没有给出完整的答案。
【问题讨论】:
标签: gcc clang c-preprocessor
当我将-I 选项与gcc/clang 一起使用时,预处理器是进行递归向下搜索还是仅搜索给定目录?我找到了this,但它没有给出完整的答案。
【问题讨论】:
标签: gcc clang c-preprocessor
您找到了 GNU 预处理器手册的一部分。您还应该阅读Header files 部分。它应该更明确地说,大致就是我在下面所说的。对于 GNU 的预处理器来说,如果不是这样,那就对了。我所说的可能仍然适用于其他预处理器(或者这可能是我的错误,但我希望不会)。
TL;DR — 预处理器没有递归搜索。
当预处理器看到时:
#include <path/to/header.h>
#include "path/to/other.h"
然后它尝试通过将#include 行中的名称添加到它内置或在命令行中指定的各种目录名称来打开头文件。对于引号中的标题,它通常从当前目录(更准确地说,包含当前文件的目录)开始,然后查找用户指定的目录,最后查找系统目录。对于用尖括号括起来的标题,它通常会省略当前目录。
因此,如果编译器查找/usr/include 并且命令行有-I /opt/package/include,那么编译器可能会尝试:
/opt/package/include/path/to/header.h
/usr/include/path/to/header.h
./path/to/other.h
/opt/package/include/path/to/other.h
/usr/include/path/to/other.h
如果在其中一个位置找不到标头,您将收到错误消息。
存在“通常”和“可能”这两个术语是因为行为是由实现定义的。尖括号和引号的搜索位置可能相同。
如果#include 指令出现在另一个头文件中,编译器可能会使用稍微不同的规则来查找嵌套的包含头文件。
表单的预处理指令
# include <h-char-sequence> new-line搜索一系列实现定义的位置以查找唯一标识的标头
<和>分隔符之间的指定序列,并导致替换 标头的全部内容指示。如何指定地点或标题 标识是实现定义的。表单的预处理指令
# include "q-char-sequence" new-line导致将该指令替换为由 " 分隔符之间的指定序列标识的源文件的全部内容。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者如果搜索失败,指令被重新处理,就像它读取一样
# include <h-char-sequence> new-line具有与原始指令相同的包含序列(包括
>字符,如果有的话)。
【讨论】: