gcc:local include path隐藏系统头文件

时间:2016-10-18 18:36:38

标签: c++ gcc makefile cmake g++

我有一个本地文件.state('main', { url: "/", templateUrl: "/app/states/frontpage/frontpage.html" }) .state('search', { parent: 'main', // parent is main, named view will find its target url : "/search/:query", views: { 'search-result@search': { template: 'successful template replacement' } } } ,它声明了一些字节交换函数。

endian.h

似乎CMake在我的makefile中生成的包含路径导致#pragma once #include <cstdint> inline uint16_t bswap(uint16_t val) { return __builtin_bswap16(val); } inline uint32_t bswap(uint32_t val) { return __builtin_bswap32(val); } ... 隐藏/usr/include/endian.h,而是解析为/usr/include/ctype.h

./src/foo/endian.h

其中一个包含路径是当前目录,与我的In file included from /usr/include/ctype.h:39:0, from /usr/include/c++/5/cctype:42, ... from ./src/foo/session.h:3 ./endian.h: In function ‘uint32_t bswap(uint32_t)’: ./endian.h:17:36: error: conflicting declaration of C function ‘uint32_t bswap(uint32_t)’ inline uint32_t bswap(uint32_t val) { return __builtin_bswap32(val); } 文件相同:endian.h

这条路径导致隐藏-I ./src/foo

使用:

/usr/include/endian.h

断裂:

g++ -I./src ./src/foo/session.cpp

我认为(明显错误的)印象是 angle-bracket 包括搜索系统路径,而 quote 包括搜索使用g++ -I./src -I./src/foo ./src/foo/session.cpp 指定的路径。

使用包含路径-I,如果来自-I./src的{​​{1}},则可行,即使它不是#include "bar/bar.h"子目录的本地(即:它找到{{} 1}}使用./src/foo/foo.h包含路径),我想这解释了我对每种包含类型含义的印象。

然而,似乎这些也会影响系统包含的发现方式(或至少如何找到尖括号包含的内容)。这是对的吗?

如果不强制我重命名我的本地foo文件,解决此问题的唯一方法是删除该包含路径吗?

2 个答案:

答案 0 :(得分:1)

最初,""<>之间确实有区别。但是,就目前而言,据我所知,所有主要编译器都同等对待。就编译器如何处理它们而言,它们之间确实没有区别。按照惯例,人们正在使用这些符号。 endian.h是标准标题,通用名称。您可能应该向下移动一个文件夹以避免名称冲突,例如"myProject/endian.h"或将名称更改为更明确的名称。

答案 1 :(得分:1)

这是gcc手册所说的包含搜索顺序:

  

查找顺序如下:

     
      
  1. 对于include指令的引号形式,将首先搜索当前文件的目录。
  2.   
  3. 对于include指令的引号形式,由-iquote选项指定的目录按从左到右的顺序搜索,如下所示:   它们出现在命令行上。
  4.   
  5. 使用-I选项指定的目录以从左到右的顺序扫描。
  6.   
  7. 使用-isystem选项指定的目录以从左到右的顺序扫描。
  8.   
  9. 扫描标准系统目录。
  10.   
  11. 使用-idirafter选项指定的目录以从左到右的顺序扫描。
  12.   

如您所见,在标准系统目录(5)(包括-I)之前,搜索由/usr/include选项(3)包含的文件。

因此,通常,用-I添加的目录中的文件将隐藏相同名称的系统头,无论这些头是包含在<>还是""中。

""<>之间的区别在于""首先包含的文件 first 搜索当前目录(和-iquote目录,但是更加晦涩难懂)。因此,如果包含#include "foo/bar.h"之类的文件,并且此文件包含“ endian.h”,则如果存在foo/endian.h,则将使用它,而不是使用标准include目录中的同名文件。但是,如果您#include <endian.h>将使用系统版本。这样,如果使用正确的引号,则可以在两个方向上减少意外的名称冲突。