在源文件中指定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?

本文关键字:前缀 include 参数 是什么 优缺点 路径 源文件 编译器 搜索      更新时间:2023-10-16

当一个C或C++库带有多个标头时,它们通常位于特定的文件夹中。例如,OpenCV在opencv文件夹中提供cv.hhighgui.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编译(