除了编译器搜索路径的方式不同,这两种#include语法之间是否存在根本差异?
我感觉英特尔的编译器输出结果并不完全相同。
除了编译器搜索路径的方式不同,这两种#include语法之间是否存在根本差异?
我感觉英特尔的编译器输出结果并不完全相同。
最根本的区别在于搜索的路径不同。
对于“系统”包含文件,应使用尖括号形式,对于项目本地包含文件,则应使用普通引号。
<>
用于“头文件”,而""
用于“源文件”。不过,“源文件”并不像你想象的那样。标准中所说的“源文件”包括我们俗称的“头文件”(以及我们通常称之为“源文件”的东西)。<>
和""
真正的区别在于,<>
用于头文件,""
用于源文件。如果你知道要包含的源代码是一个文件,那么应该使用""
。<>
和""
使用不同的搜索算法。这是允许的,因为标准规定任何一种都是实现定义的。但这并不是标准所表达的真正区别。#include <...>
这里讲的是头文件,它们不一定是文件系统中的文件,也可以是编译器内部的文件。
#include "..."
#include指令用于包含文件,仅当找不到这样的文件时,才会默认回退到#include <...>
。
这些头文件和文件在哪里以及如何查找,以及是否应该使用<>来表示系统文件,使用""来表示项目文件,这确实是一个常见的约定,完全取决于编译器和项目。
C标准(ISO/IEC 9899:1999)如下所述(重点在于我):
6.10.2 源文件包含
限制
#include
指令应该标识可以由实现处理的头文件或源文件。语义
形如
#include <h-char-sequence> new-line
的预处理指令搜索一系列由实现定义的地方,以特定序列唯一标识的标题为界定符,替换该指令的整个内容。如何指定这些地方或标识头文件是实现定义的。
形如
#include "q-char-sequence" new-line
的预处理指令将该指令的内容替换为由指定序列标识的源文件的整个内容,该序列在引号之间。命名的源文件按照实现定义的方式进行搜索。如果不支持此搜索,或者搜索失败,则将指令重新处理,就好像它读取了
#include <h-char-sequence> new-line
从原始指令中包含相同的包含序列(包括>字符,如果有)。
引号指示先在当前目录中搜索,然后在系统目录中搜索(路径要么是编译器/预处理器硬编码的,要么是用-I
指定的)。使用尖括号可以选择不首先搜索当前目录。
编译器输出绝对不会依赖于引号,因为它在预处理阶段处理。除非由于更改的搜索行为而包含了不同的文件。
#include <somefile.h>
将检查系统包含路径(包括为项目添加的任何其他路径)。
#include "somefile.h"
将检查应用程序的工作文件夹。(即与具有#include语句的源文件相同的文件夹)。
警告:这只是纯粹的猜测。我没有足够的经验来了解英特尔编译器是否以这种方式工作,也不知道是否有任何编译器可以这样做。
如果编译器实现了预编译头文件,则可能会将其用于一种包含形式,但不用于另一种。如果预编译头文件与实际头文件不同步,那么根据所包含的内容不同,您将得到不同的结果。
一般来说,没有技术上的区别,任何人告诉你关于它的一切都只是本地风格,可能受过去编译器的影响 - 许多现代编译器以完全相同的方式实现初始搜索(通常可以通过命令行选项获得其他常见行为)。标准将行为留给实现者处理,没有特定的理由支持两种语法。
根据ISO C99标准的第6.10.2节,<>和""的搜索路径都是实现定义。 标准视角下它们之间唯一的区别是,如果无法解析,使用""将回退到<>。(不要被标准似乎在“头文件”和“源文件”之间进行区分所绊倒 - 实际上除了某些名称被保留 - “stdio.h”等之外,标准并没有定义区别。)