简体   繁体   English

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

[英]Which directories does include statement search in C/C++?

test.c : test.c

#include "file.h"

In the above statement, which directories will be searched ? 在上面的语句中,将搜索哪些目录?

I suppose the directory where test.c locates will be searched, right? 我想将检索test.c所在的目录,对吗?

But is that all? 但这就是全部吗?

BTW, what's the benefit to use a header file? 顺便说一下,使用头文件有什么好处? Java doesn't require a header file... Java不需要头文件......

  • #include <header_name> : Standard include file: look in standard paths (system include paths setup for the compiler) first #include <header_name> :标准包含文件:首先查看标准路径(系统包括编译器的路径设置)
  • #include "header_name" : Look in current path first, then in include path (project specific lookup paths) #include "header_name" :首先查看当前路径,然后查看包含路径(项目特定查找路径)

The benefit of using a header file is to provide others with the interface of your library, without the implementation. 使用头文件的好处是为其他人提供库的接口,而无需实现。 Java does not require it because java bytecode or jar is able to describe itself (reflexion). Java不需要它,因为java字节码或jar能够描述自己(反射)。 C code cannot (yet) do it. C代码不能(还)做到这一点。

In Java you would only need the jar and have the correct use statement. 在Java中,您只需要jar并具有正确的use语句。 In C you will (mostly) need a header and a lib file (or header and dll). 在C中,您(大多数时候)需要一个头文件和一个lib文件(或头文件和dll)。

The other reason is the way c code is compiled. 另一个原因是编译c代码的方式。 The compiler compiles translation units (ac/cpp file with all included headers) and the linker in a second step links the whole stuff. 编译器编译转换单元(带有所有包含头的ac / cpp文件),第二步中的链接器链接整个内容。 Declarations must not be compiled, and this saves time and avoid code to be useless generated for each compilation unit which the linker would have to cleanup. 不得编译声明,这样可以节省时间并避免为链接器必须清理的每个编译单元生成无用的代码。

This is just a general idea, I am not a compiler specialist but should help a bit. 这只是一个普遍的想法,我不是编译专家,但应该有所帮助。

It's controlled by your compiler. 它由您的编译器控制。 For example, gcc has a -I option to specify the include path. 例如,gcc具有-I选项以指定包含路径。

C and C++ prototypes are required so the compiler (distinguished from the linker) can make sure functions are being called with the correct arguments. C和C ++原型是必需的,因此编译器(与链接器不同)可以确保使用正确的参数调用函数。 Java is different in that the compiler uses the binary .class files (which unlike C are in a standard bytecode format with all type information preserved) to check that calls are valid. Java的不同之处在于编译器使用二进制.class文件(与C不同,它们采用标准字节码格式并保留所有类型信息)来检查调用是否有效。

Using quotes after the #include instructs the preprocessor to look for include files in the same directory of the file that contains the #include statement, and then in the directories of any files that include (#include) that file. #include之后使用引号指示预处理器在包含#include语句的文件的同一目录中查找包含文件,然后在包含(#include)该文件的任何文件的目录中查找。 The preprocessor then searches along the path specified by the /I compiler option, then along paths specified by the INCLUDE environment variable. 然后,预处理器沿/ I编译器选项指定的路径搜索,然后沿INCLUDE环境变量指定的路径搜索。

If you use the angle bracket form, it instructs the preprocessor to search for include files first along the path specified by the /I compiler option, then, when compiling from the command line, along the path specified by the INCLUDE environment variable. 如果使用尖括号形式,它指示预处理器首先沿/ I编译器选项指定的路径搜索包含文件,然后在从命令行编译时,沿INCLUDE环境变量指定的路径搜索。

strace , or truss , etc., may be helpful. strace ,或truss等可能会有所帮助。 For example, create a file foo.c with the single line #include "foo.h" . 例如,使用单行#include "foo.h"创建文件foo.c Then on CYGWIN, the command: 然后在CYGWIN上,命令:

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

produces: 生产:

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/

I was actually surprised this list was so short: the last time I did this exercise, on SunOS 4 fifteen years ago, the search path had over a dozen directories. 我真的很惊讶这个名单太短了:上次我做这个练习,十五年前在SunOS 4上,搜索路径有十几个目录。

The first directory, obviously, is where foo.c lives. 显然,第一个目录是foo.c所在的位置。 See aslo http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html for the environment variables CPATH and C_INCLUDE_PATH . 有关环境变量CPATHC_INCLUDE_PATH请参阅http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html But these are not set on my machine. 但这些都没有在我的机器上设置。 (And I am unclear whether CYGWIN uses them, anyway.) (无论如何,我不清楚CYGWIN是否使用它们。)

Edit: The simplest solution is to use cpp -v ( not gcc -v). 编辑:最简单的解决方案是使用cpp -v而不是 gcc -v)。 It gives: 它给:

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.

The C++ Standard doesn't really say which directories should be searched. C ++标准并没有真正说明应该搜索哪些目录。 This is how the C++ Standard describes what happens when #include "somefile.h" is encountered: 这就是C ++标准描述遇到#include "somefile.h"时会发生什么的方法:

A preprocessing directive of the form 表单的预处理指令

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

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read 导致由“delimiters”之间的指定序列标识的源文件的全部内容替换该指令。以实现定义的方式搜索指定的源文件。如果不支持此搜索,或者搜索失败,该指令被重新处理,就像它读取一样

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

with the identical contained sequence (including > characters, if any) from the original directive. 使用原始指令中相同的包含序列(包括>字符,如果有的话)。

So exactly what directories are searched are at the mercy of your specific C++ implementation. 因此,确切搜索的目录是否受您特定C ++实现的支配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM