哪些目录在C/C++中包含语句搜索?

问题描述:

test.c哪些目录在C/C++中包含语句搜索?

#include "file.h" 

在上面的语句,目录将被搜索?

我想test.c所在的目录将被搜索,对不对?

但是,所有?

顺便说一句,使用头文件有什么好处? Java不需要头文件...

+0

哪个编译器/平台? – Stephen 2010-06-11 16:27:11

它由您的编译器控制。例如,gcc有一个-I选项来指定包含路径。

C和C++原型是必需的,所以编译器(区别于链接器)可以确保函数被正确的参数调用。 Java不同之处在于,编译器使用二进制.class文件(与C不同,它以标准字节码格式保存所有类型信息)来检查调用是否有效。

+0

但是应该有一些默认的搜索路径,比如'stdlib.h'所在的位置,对吧? – user198729 2010-06-11 16:12:00

+1

您的问题询问''test.h“',而不是''。像stdlib.h这样的标准头文件使用括号语法(''),并且这些头文件位于默认系统路径中。 – 2010-06-11 16:13:38

  • #include <header_name>:标准包含文件:看在标准路径(系统包括编译器的路径设置)第一
  • #include "header_name":看看在当前路径,然后再在包含路径(项目特定查找路径)

使用头文件的好处是为其他人提供库的接口,而无需实现。 Java并不要求它,因为Java字节码或jar能够描述自己(反射)。 C代码不能(但)做到这一点。

在Java中,您只需要jar并拥有正确的使用语句。在C中,你将(主要)需要一个头文件和一个lib文件(或者头文件和dll文件)。

另一个原因是c代码编译的方式。编译器编译翻译单元(一个包含所有头文件的c/cpp文件),链接器在第二步中链接整个东西。声明不能被编译,这样可以节省时间,并避免代码被链接器清理的每个编译单元无用地生成。

这只是一个普遍的想法,我不是一个编译器专家,但应该有所帮助。

+0

什么是标准路径,为什么C/C++中不可能使用反射? – user198729 2010-06-11 16:13:01

+0

存在系统头文件的系统(可能依赖于编译器)路径。例如,* nix系统倾向于使用'/ usr/include /'等 – Dusty 2010-06-11 16:15:37

+0

标准包含路径是系统特定的,并且在C++中根本不需要使用文件系统。编译器无法使用编译的库检查类型的原因是该类型信息并未全部保留,并且没有标准的ABI(应用程序二进制接口)。 – 2010-06-11 16:17:58

#include之后使用引号指示预处理器在包含#include语句的文件的同一目录中查找包含文件,然后在包含(#include)该文件的任何文件的目录中查找包含文件。预处理器然后沿着由/ I编译器选项指定的路径搜索,然后沿着由INCLUDE环境变量指定的路径搜索。

如果使用尖括号形式,它将指示预处理器首先沿着/ I编译器选项指定的路径搜索包含文件,然后在从命令行进行编译时沿着由INCLUDE环境指定的路径变量。

+0

需要注意的是,当使用尖括号时,除非当前目录位于路径中,否则编译器不*查看当前目录。因此,如果'#include '''#include '(注意没有路径),并且bh与ah在同一个目录中,'#include '将会失败if该目录不在路径中。 – 2010-06-11 18:01:00

+0

正是由于这个原因,我经常咆哮人们应该几乎从不在他们自己的代码中使用#include语句中的尖括号,但是这种咆哮通常是充耳不闻。 – 2010-06-11 18:02:06

strace桁架等可能有帮助。例如,使用单行#include "foo.h"创建一个文件foo.c。然后在Cygwin的命令:

strace /usr/bin/gcc-4.exe foo.c | grep 'src_path.*foo.h,' | sed 's/.*src_path //;s/foo.h.*//' 

生产:

foo.c:1:22: error: foo.h: No such file or directory 

/home/Joe/src/utilities/ 
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/ 
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed/ 
/usr/include/ 
/usr/include/w32api/ 

实际上,我是惊讶这个名单是如此之短:上一次我十五年前做这个测试,在SunOS 4,搜索路径有十几个目录。

显然,第一个目录是foo.c存在的地方。环境变量CPATHC_INCLUDE_PATH的环境变量见http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html。但是这些没有在我的机器上设置。 (而且我不清楚是否CYGWIN使用它们,反正。)

编辑:最简单的解决方法是使用cpp -vGCC -v)。它给出:

COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i686' 
/usr/lib/gcc/i686-pc-cygwin/4.3.4/cc1.exe -E -quiet -v -D__CYGWIN32__ -D__CYGWIN__ 
     -Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../.. 
     /include/w32api -idirafter 
     /usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api - 
     -mtune=generic -march=i686 
ignoring nonexistent directory "/usr/local/include" 
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/include" 
ignoring duplicate directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api" 
#include "..." search starts here: 
#include <...> search starts here: 
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include 
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed 
/usr/include 
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../include/w32api 
End of search list. 
+0

编辑:和更多的gcc文档:http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html#Search-Path – 2010-06-11 21:07:55

C++标准并没有说明应该搜索哪些目录。这是C++标准是如何描述时#include "somefile.h"遇到什么情况:

形式

# include "q-char-sequence" new-line 

的预处理指令由源文件中标识的 的全部内容导致的替代品。 指令由 指定的序列之间的“ ”分隔符。指定的源文件是 搜索 执行定义的方式。如果这个 搜索不是支撑,或者如果 搜索失败,该指令是 再处理,就好像它与含有相同序列 读

# include <h-char-sequence> new-line 

(包括>字符,如果有的话)从 原始指令。

那么究竟是哪些目录被搜索是在你的具体C++实现的摆布。

+0

@ Neil:在我的机器上,'-print-search-dirs'不包括任何包含目录。 – 2010-06-11 19:29:45

+0

@Joseph B * gger。你是对的 - 我可以发誓这样做,但它只打印可执行文件和库搜索路径。 – 2010-06-11 19:35:49