包含标头中的搜索路径因编译器而异

Include search paths from included header varies for different compilers

本文关键字:编译器 路径 搜索 包含标      更新时间:2023-10-16

我有以下文件夹结构:

project
├── header1.h
├── folder
│   └── header2.h
└── main.cpp

以下来源:

//main.cpp
#include "header1.h"
#include "folder/header2.h"
int main() {}
//header1.h
#pragma once
void function1() {}
//folder/header2.h
#pragma once
#include "header1.h"
void function2() {}

所以"header2.h"包括不在同一文件夹中的"header1.h"。

使用cl main.cpp编译此代码是成功的:

Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.
main.cpp Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.
/out:main.exe main.obj

但是对于gcc main.cpp我得到错误:

In file included from main.cpp:2:0:
folder/header2.h:2:21: fatal error: header1.h: No such file or directory
#include "header1.h"
^
compilation terminated.

这完全有道理。似乎Microsoft正在使用自己的规则来解决包含问题。 有没有办法为cl(和Visual Studio)禁用此行为? 有没有办法为gcc启用类似 cl 的行为?


上。

我已经在Windows上使用Clang 4.0.0clang++ main.cpp进行了检查:

In file included from main.cpp:2:
./folder/header2.h:2:10: warning: #include resolved using non-portable Microsoft search rules as: ./header1.h

[-微软-包括] #include "标题1.h" ^ 生成 1 条警告。

它甚至为此-Wmicrosoft-include了特定的规则。

本文解释了VC++如何处理include指令的两种形式(""<>)。

我想""表单的第(3)点会导致对项目中可能的包含目录进行非常广泛的搜索:

报价表格

(3)在当前打开的包含文件的目录中,在 它们的打开顺序相反。搜索从 父包含文件的目录,并继续向上通过 任何祖父项的目录都包含文件。

这就是为什么当header2.h从内部处理时main.cpp,其中还包括header1.h,它不会给您任何错误。

GCC 搜索规则完全不同:

  1. 对于 include 指令的引用形式,首先搜索当前文件的目录。
  2. 对于 include 指令的引用形式,由 -iquote 选项指定的目录按从左到右的顺序搜索,如 它们显示在命令行上。
  3. 使用 -I 选项指定的目录按从左到右的顺序进行扫描。
  4. 使用 -isystem 选项指定的目录按从左到右的顺序进行扫描。
  5. 扫描标准系统目录。
  6. 使用 -idirafter 选项指定的目录按从左到右的顺序进行扫描。

它不会自动搜索到目前为止打开的包含文件的目录(之前包括),这是导致错误的原因。我认为没有办法绕过这个限制并强制任何一个编译器使用另一个编译器使用的搜索逻辑。