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

Seb*_*ach 70 c c++ gcc g++ c++-faq

g++ 给我错误的形式:

foo.cc:<line>:<column>: fatal error: <bar>: No such file or directory
compilation terminated.
Run Code Online (Sandbox Code Playgroud)

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

这是为什么?


请注意:此问题之前已被多次询问过,但每次都是针对问题情况的.这个问题的目的是提出一个问题,即其他人可以一劳永逸地重复关闭 ; 一个常见问题.

Seb*_*ach 97

您的编译器只是尝试编译名为的文件foo.cc.点击行号后line,编译器会发现:

#include "bar"
Run Code Online (Sandbox Code Playgroud)

要么

#include <bar>
Run Code Online (Sandbox Code Playgroud)

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

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

g++有一个选择-I.它允许您将包含搜索路径添加到命令行.想象一下,您的文件bar位于一个名为frobnicate,相对于的文件夹中foo.cc(假设您正在从所在的目录进行编译foo.cc):

g++ -Ifrobnicate foo.cc
Run Code Online (Sandbox Code Playgroud)

您可以添加更多包含路径; 你给出的每一个都是相对于当前目录的.Microsoft的编译器具有相同的关联选项/I,或者在Visual Studio中,可以在项目的属性页中,在Configuration Properties-> C/C++ - > General-> Additional Include Directories下设置文件夹.

现在假设你有bar不同文件夹的多个版本,给出:


// A/bar
#include<string>
std::string which() { return "A/bar"; }
Run Code Online (Sandbox Code Playgroud)
// B/bar
#include<string>
std::string which() { return "B/bar"; }
Run Code Online (Sandbox Code Playgroud)
// C/bar
#include<string>
std::string which() { return "C/bar"; }
Run Code Online (Sandbox Code Playgroud)
// foo.cc
#include "bar"
#include <iostream>

int main () {
    std::cout << which() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

最重要的#include "bar"是最左边:

$ g++ -IA -IB -IC foo.cc
$ ./a.out
A/bar
Run Code Online (Sandbox Code Playgroud)

正如你看到的,当编译器开始寻找通过A/,B/并且C/,它停在第一个或最左边打.

这两种形式的真实,include <>incude "".

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

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

例如:

想象一下,项目文件夹中有以下文件:

list
main.cc
Run Code Online (Sandbox Code Playgroud)

main.cc:

#include "list"
....
Run Code Online (Sandbox Code Playgroud)

为此,您的编译器将#include文件list放在项目文件夹中,因为它当前正在编译main.cc并且list当前文件夹中有该文件.

但是main.cc:

#include <list>
....
Run Code Online (Sandbox Code Playgroud)

然后g++ main.cc,您的编译器将首先查看系统文件夹,因为它<list>是一个标准头文件,它将作为标准库的一部分与您的C++平台一起提供#include的文件名称list.

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

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

根据gcc文档,在include <>"普通的Unix系统"上,优先级如下:

 /usr/local/include
 libdir/gcc/target/version/include
 /usr/target/include
 /usr/include
Run Code Online (Sandbox Code Playgroud)

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

文件还说明:

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

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

g++ -I. main.cc
Run Code Online (Sandbox Code Playgroud)

#include<list>
int main () { std::list<int> l; }
Run Code Online (Sandbox Code Playgroud)

事实上,-I.优先考虑.系统上的文件夹包含,我们得到编译器错误.

  • @Jeffrey:也许这个问题的作者想要符合这里的一般格式.不知道,问他. (25认同)
  • 只是想让你注意到你将编译器称为"你的编译器"有点奇怪,因为问题和答案是同一个作者. (9认同)
  • "_Imagine你的文件栏位于一个名为frobnicate的文件夹中,相对于foo.cc_",用`-I`给出的目录是相对于你运行gcc的dir,而不是相对于正在编译的文件.如果你做`g ++ -Ifrobnicate blah/foo.cc`,差别很大 (5认同)
  • (在Linux系统上)“ PATH”环境变量的设置是否会影响编译器搜索文件的方式? (2认同)