关于C语言include尖括号和双引号的对话

A: #include "..." 和 #include <...> 有什么区别?linux

B: 他喵的, 这么简单的问题. 尖括号是先在系统目录下找, 双引号是首先在当前目录下找, 找不到就找系统目录.shell

A: 说得很含糊. 那么我问你, 当前目录有个叫hdr.h的文件,
    当前目录下还有一个子目录sub, sub里面有两个文件hdr.h和1.c,
    1.c中#include "hdr.h",
    那么在当前目录编译sub/1.c, 它应该包含哪个hdr.h?
bash

   bash-3.2$ tree
   |-- sub
   |   |-- 1.c
   |   `-- hdr.h
   `-- hdr.h
   bash-3.2$ cat sub/1.c
   #include "hdr.h"
   bash-3.2$ gcc -c sub/1.c

B: 应该包含外面的hdr.h吧, 由于它在gcc工做的当前目录, 而子目录的hdr.h不在当前目录, 应该搜不到.
spa

A: 错, 包含的是sub/hdr.h !命令行

B: 啊!... 喔... 双引号是首先在使用include的源文件所在目录找(也就是1.c所在的目录sub找), 而不是编译器当前工做目录找, 我原来理解错了.设计

A: 是的, gcc和msvc的include双引号都是先在使用include的源文件所在目录找.code

B: C99标准是怎么规定的? 是源文件当前目录仍是编译器工做目录?编译器

A: 其实C99标准没有规定#include "..." 先找哪一个目录, 只说取决于实现, 你能够设计一个C编译器include双引号时按你设计的方式找(若是找不到退化为#include <...>). 但事实上的工业标准是"双引号优先从使用include的源文件所在目录".编译

B: 明白了.class

A: 那么我再问你, #include <...> 所谓的"从系统目录找", 那么"系统目录"到底有哪些, 怎么看呢?

B: 编译时-I指定的目录呗.

A: 若是没指定-I的参数时, 是否是系统目录列表就是空的?

B: 固然不是, 有默认的吧.

A: 怎么看默认的?

B: 这个不知道. 怎么看?

A: 以gcc为例, 在命令行运行 echo | gcc -E -v -

   bash-3.2$ echo | gcc -E -v -
   * * *
   #include "..." search starts here:
   #include <...> search starts here:
   /usr/lib/gcc/i686-pc-linux-gnu/4.8.2/include
   /usr/local/include
   /usr/lib/gcc/i686-pc-linux-gnu/4.8.2/include-fixed
   /usr/include
   End of search list.

B: 那么我指定gcc -I. 时是把 . 做为搜索路径仍是把当前目录转成绝对路径加入到列表中呢?

A: 这个问题问得好! 其实我也不知道, 要不咱们试一下.

   bash-3.2$ echo | gcc -E -v -I. -
   * * *
   #include "..." search starts here:
   #include <...> search starts here:
   .
   /usr/lib/gcc/i686-pc-linux-gnu/4.8.2/include
   /usr/local/include
   /usr/lib/gcc/i686-pc-linux-gnu/4.8.2/include-fixed
   /usr/include
   End of search list.

B: 并无转成绝对路径, 就是一个点.

A: 恩, 那么问题来了, 下面这种情形下( 注意: 1.c的内容修改成 #include <hdr.h> ), 会包含那个hdr.h ?

   bash-3.2$ tree
   |-- sub
   |   |-- 1.c
   |   `-- hdr.h
   `-- hdr.h
   bash-3.2$ cat sub/1.c
   #include <hdr.h>
   bash-3.2$ gcc -c -I. sub/1.c

B: 我猜会用子目录的hdr.h.

A: 我猜会用外层的hdr.h,
    在hdr.h写个1,
    在sub/hdr.h写个2,
    而后 gcc -E -I. sub/1.c.
    你看结果是1, 我猜对了!

B: 嗯, 看来搜索路径列表是基于编译器工做路径的.

相关文章
相关标签/搜索