在源文件中指定include前缀与在编译器的搜索路径参数中指定include前缀的优缺点是什么
What are the pros and cons of specifying an include prefix in the source file versus in the search path parameter of the compiler?
当一个C或C++库带有多个标头时,它们通常位于特定的文件夹中。例如,OpenCV在opencv
文件夹中提供cv.h
和highgui.h
。
包含它们的最常见方法是将此opencv
文件夹添加到预编译器的搜索路径中(例如gcc -I/pathto/opencv
(,并简单地将标题按文件名包含在源文件中(例如,#include <cv.h>
(
还有一种选择,因为包含标题的文件夹经常与父文件夹中的其他文件夹(例如/usr/include
或开发团队通用的某个路径(在一起。在这种情况下,如果父文件夹已经在路径中,那么在源文件(例如#include <opencv/cv.h>
(中指定头文件夹就足够了。
我能想到的这个替代方案的唯一问题是,在一个系统中,所有标题都在一个文件夹中。然而,这种替代方案可以防止歧义(例如,如果两个库具有vector.h
头(,使建立另一个构建系统变得更容易,并且可能在预编译器搜索头文件方面更有效。
根据这一分析,我倾向于选择另一种,但我在互联网上发现的绝大多数代码都是第一种。例如,谷歌为"#include <cv.h>"
返回了大约218000个结果,而为"#include <opencv/cv.h>"
返回了79100个结果。我是错过了共同方式的优点,还是错过了替代方式的缺点?
我个人更喜欢<opencv/cv.h>
。
为什么?因为我是人,大脑有限,要做的事情比记住cv.h
来自opencv
库要重要得多。
因此,即使我使用的库总是在专用文件夹中,我也会将它们构造为:
<specific library folder>/include/<library name>/...
这有助于我记住这些标题的来源。
我知道有人说这没用,IDE无论如何都会直接把你带到文件中。。。但是
- 我并不总是使用IDE
- 我并不总是想打开每个include文件,仅仅是为了知道这个特定文件绑定到哪些库
它还使组织包含列表(以及将相关包含分组在一起(变得更加容易。
它们的用途略有不同,我认为需要小心使用。
考虑以下事实:在-I
的情况下,它是/pathto/opencv
。你建议可能是#include <opencv/cv.h>
,但你永远不会写#include </pathto/opencv/cv.h>
。这是有原因的,那就是你希望cv.h
总是在一个名为opencv
的目录中,因为它总是这样发布的,而pathto
只是库文件碰巧安装在你的机器上(或你的发行版上,不管怎样(的地方。
根据代码的编译位置,任何可能不同的内容都应该在include路径中,这样就可以在不修改源代码的情况下对其进行配置。任何保证在任何使用特定cv.h
的地方都是相同的东西都可以出现在源中,但它不是必须的,所以我们需要决定是否需要它。
正如您已经注意到的,将其作为消歧器是很有用的,尤其是对于具有两个字符名称的文件,但如果您认为有人可能想将cv.h
放在不同的位置,那么您应该将其忽略。这几乎就是你所做的权衡——头应该总是在opencv
目录中,但作为消除歧义的代价,你值得依赖它作为保证吗?
我想使用#include <opencv/cv.h>
的主要问题是您不一定要添加整个父路径。
举一个例子,当使用带有完整路径的选项时,它已安装到/usr/local
,您需要将-I/usr/local/include
添加到命令行中。这可能会产生各种副作用。
例如,对于一个完全不同的应用程序,可能有人在那里安装了GNU iconv库。然后,突然间,您的应用程序(也在执行#include <iconv.h>
(从独立的iconv库中获取头,而不是在glibc中实现。
显然,这些问题确实会不时出现,但通过包含更具体的目录,您有望将其最小化。
第一个版本的原因:
- 您并不总是能够在标准路径中安装头文件/库。有时您没有root访问权限
- 您不想为已安装的所有库添加所有路径,从而污染路径
- 例如,您可以安装同一个库的两个版本(在您的案例中是openCV(,并且您希望一些项目使用一个库编译,另一些项目使用另一个库。如果你把它们放在路径上,那么你会得到一个名称冲突。对我来说,这是主要原因之一(确切地说,对于OpenCv,我安装了1.x和2.x版本,一些项目用1.x编译,一些用2.x编译(
- 既然存在危险,为什么项目要使用-I include开关
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 如何将更多文件夹添加到c++include路径
- 什么是"#include <boost/functional/hash.hpp> "?
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- C++包含来自 #include "DevEngine/Core.h" 的错误
- 编译器如何在前缀和 postix 运算符之间进行区分?
- <filesystem> 在 clang 6 和 10 上 #include 错误
- 在 void 函数中使用 #include 变量C++
- 查找带有 Anaconda cmake 前缀的 boost-python3
- N-API include an .so or dll
- 迭代器类的重载前缀增量运算符会引发分段错误
- 允许哪些令牌作为 #include 的参数?
- 如何在友元函数中使用静态成员而不添加前缀 [类名]::
- 生成前缀位掩码
- GCC 包含标头(使用"-include")CMake 未检测到的更改
- WebAssembly include OpenCV
- 如何在 c++ 中正确指定 #include 路径以使程序可移植
- 指示编译器忽略在#include中找到的标头前缀
- 在源文件中指定include前缀与在编译器的搜索路径参数中指定include前缀的优缺点是什么