gcc/g : "没有这样的文件或目录"

新手上路,请多包涵

g++ 给我以下形式的错误:

 foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.

gcc 编译 C 程序时也是如此。

这是为什么?


请注意: 这个问题以前被问过很多次,但每次都是针对提问者的情况。这个问题的目的是 提出一个问题,其他人可以一劳永逸地关闭作为重复的问题; _常见问题解答_。

原文由 Sebastian Mach 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

您的编译器刚刚尝试编译名为 foo.cc 的文件。在点击行号 line 时,编译器发现:

 #include "bar"

或者

#include <bar>

然后编译器尝试找到该文件。为此,它使用一组目录进行查看,但在这组目录中,没有文件 bar 。有关 include 语句版本之间差异的解释,请参见 此处

如何告诉编译器在哪里找到它

g++ 有一个选项 -I 。它允许您将包含搜索路径添加到命令行。 Imagine that your file bar is in a folder named frobnicate , relative to foo.cc (assume you are compiling from the directory where foo.cc is位于):

 g++ -Ifrobnicate foo.cc

您可以添加更多包含路径;你给的每一个都是相对于当前目录的。 Microsoft 的编译器有一个相关选项 /I 工作方式相同,或者在 Visual Studio 中,可以在项目的属性页中设置文件夹,在配置属性->C/C++->常规- >其他包含目录。

现在假设您在不同的文件夹中有多个版本的 bar ,给定:


 // A/bar
#include<string>
std::string which() { return "A/bar"; }


 // B/bar
#include<string>
std::string which() { return "B/bar"; }


 // C/bar
#include<string>
std::string which() { return "C/bar"; }


 // foo.cc
#include "bar"
#include <iostream>

int main () {
    std::cout << which() << std::endl;
}


#include "bar" 的优先级是最左边的:

 $ g++ -IA -IB -IC foo.cc
$ ./a.out
A/bar

如您所见,当编译器开始查看 A/B/C/ 时,它停止在第一个或最左边的命中。

这两种形式都是如此, include <>incude ""

\#include <bar>\#include "bar" 之间的区别

通常, #include <xxx> 使其首先查看系统文件夹, #include "xxx" 使其首先查看当前或自定义文件夹。

例如:

假设您的项目文件夹中有以下文件:

 list
main.cc

main.cc

 #include "list"
....

For this, your compiler will #include the file list in your project folder, because it currently main.cc and there is that file list 在当前文件夹中。

但是使用 main.cc

 #include <list>
....

and then g++ main.cc , your compiler will look into the system folders first, and because <list> is a standard header, it will #include the file named list 作为标准库的一部分随您的 C++ 平台一起提供。

这有点简化,但应该给你基本的想法。

详细信息 <> / "" -priorities 和 -I

根据 gcc-documentationinclude <> 在“普通 Unix 系统”上的优先级如下:

  /usr/local/include
 libdir/gcc/target/version/include
 /usr/target/include
 /usr/include

对于 C++ 程序,它也会首先在 /usr/include/c++/version 中查找。在上面,target 是系统 GCC 被配置为编译代码的规范名称; […]。

该文档还指出:

您可以使用 -Idir 命令行选项添加到此列表。 在默认目录之前,按从左到右的顺序搜索所有由 -I 命名的目录。唯一的例外是默认情况下已经搜索了 dir。在这种情况下,该选项将被忽略,系统目录的搜索顺序保持不变。

继续我们的 #include<list> / #include"list" 示例(相同的代码):

 g++ -I. main.cc

#include<list>
int main () { std::list<int> l; }

事实上, -I. 优先于系统包含的文件夹 . 并且我们得到一个编译器错误。

原文由 Sebastian Mach 发布,翻译遵循 CC BY-SA 3.0 许可协议

此外,似乎存在编译器错误,如果您在头文件名中包含字符“struct”或“Struct”,编译器将抛出相同的“没有这样的文件或目录”错误。

原文由 Robert Frederick 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题