为了账号安全,请及时绑定邮箱和手机立即绑定

标题的相对路径(例如“ ../include/header.h”)有什么好处?

标题的相对路径(例如“ ../include/header.h”)有什么好处?

C
小唯快跑啊 2019-10-11 09:49:35
我已经审查了问题:如何正确使用include指令和C ++ #include语义,并且既没有解决这个问题,也没有解决SO在输入标题时建议的其他问题...编写的好处(如果有)是什么:#include "../include/someheader.h"#include "../otherdir/another.h"与仅使用纯文件名相比:#include "someheader.h"#include "another.h"或不带' ..' 的相对名称:#include "include/someheader.h"#include "otherdir/another.h"我看到的问题是:您不能移动标题而不必担心哪些源文件包含它。您最终可能会为依赖项和错误报告中的标头提供非常长的路径。我今天有一个与“ ../dir1/include/../../include/../dir2/../include/header.h”。我看到的唯一优点是,尽管您不需要移动文件,但可能不必总是使用' -I'指令来查找标头就可以摆脱困境,但是却失去了灵活性,并且在sub-sub中进行编译非常复杂目录等似乎超过了收益。那么,我是否忽视了好处?感谢您的投入。我认为,共识是使用“ ..”这个符号并没有太大的好处。一般而言,我喜欢“ somewhere / header.h”表示法。我确实在新项目中使用了它。我正在研究的东西不是什么新东西。其中一个问题是,有各种套头的,往往带有前缀,如rspqr.h,rsabc.h,rsdef.h,rsxyz.h。这些都与rsmp目录中的代码相关,但是某些标头位于其中,rsmp而其他标头位于中央的include目录中,该目录中没有诸如此类的子目录rsmp。(然后对代码的其他各个部分重复上述操作;在多个位置都有标头,而其他位的代码则随机需要。)随处移动内容是一个主要问题,因为多年来这些代码变得如此复杂。并且makefile在-I提供的选项中不一致。总而言之,这是一个数十年来不那么良性的忽视的悲惨故事。修复所有问题而不破坏任何东西将是一项漫长而乏味的工作。
查看完整描述

3 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

问题#include "../include/header.h"在于它经常会偶然工作,然后看似无关的更改将使其稍后停止工作。


例如,考虑以下源布局:


./include/header.h

./lib/library.c

./lib/feature/feature.c

假设您使用的包含路径运行编译器-I. -I./lib。怎么了?


./lib/library.c可以做到#include "../include/header.h",这是有道理的。

./lib/feature/feature.c#include "../include/header.h"即使没有任何意义,也可以做到。这是因为编译器将尝试#include相对于当前文件位置的指令,如果失败,它将尝试#include相对于路径中每个-I条目的指令#include。

此外,如果您稍后-I./lib从#include路径中删除,则会中断./lib/feature/feature.c。


我发现以下内容更可取:


./projectname/include/header.h

./projectname/lib/library.c

./projectname/lib/feature/feature.c

我不会添加任何包括比其他路径项-I.,然后双方library.c并feature.c会使用#include "projectname/include/header.h"。假设“项目名称”可能是唯一的,那么在大多数情况下,这不应导致名称冲突或模棱两可。VPATH如果绝对必要,您还可以使用include路径和/或make 功能在多个目录之间划分项目的物理布局(例如,以适应特定于平台的自动生成的代码;这在使用时确实会崩溃#include "../../somefile.h")。

查看完整回答
反对 回复 2019-10-11
?
月关宝盒

TA贡献1772条经验 获得超5个赞

在以下情况下,请#include ""使用一个或多个“ ../” 序列开始指令的路径:


您要包含一个与包含文件的搭配是固定的文件,并且

您在POSIX系统或VC ++上构建,并且

您希望避免对要包含的文件有歧义。

总是很容易提供一个示例,说明您的代码库中包含错误,并在此之后导致难以诊断的错误。但是,即使您的项目没有故障,但如果您依靠绝对路径来指定相对于彼此的文件,则第三方可能会滥用该项目。


例如,考虑以下项目布局:


./your_lib/include/foo/header1.h

./your_lib/include/bar/header2.h

./their_lib/include/bar/header2.h

your_lib / include / foo / header1.h应该如何包含your_lib / include / bar / header2.h?让我们考虑两个选项:


#include <bar/header2.h>


假设your_lib / include和their_lib / include都被引为标头搜索路径(例如,使用GCC -I或-isystem选项),那么将选择哪个header2.h对搜索这两个路径的顺序很敏感。


#include "../bar/header2.h"


编译器将搜索的第一个位置是your_lib / include / foo / header1.h的位置,即your_lib / include / foo /。它将首先尝试your_lib / include / foo /../ bar / header2.h,该文件会缩小为your_lib / include / bar / header2.h,在其中可以找到正确的文件。标头搜索路径将完全不使用,并且几乎没有歧义。


出于给出的原因,在这种情况下,我强烈建议您选择选项2)。


针对其他答案中的一些论点:


@ andrew-grant 说:


...非常清楚标头文件属于哪个名称空间或模块。


也许。但是相对路径可以解释为“在同一模块中”。如果在不同模块中存在多个具有相同名称的目录,它们将提供清晰的信息。


@ bk1e 说:


...它经常会偶然地工作...


我认为相对路径仅在非常罕见的情况下会偶然起作用,在极少数情况下,项目从一开始就被破坏并且很容易修复。在不引起编译器错误的情况下经历这样的名称冲突似乎不太可能。一种常见的情况是,从属项目的文件包含一个标题,而另一个包含另一个标题。与该从属项目隔离进行编译时,编译测试套件应导致“没有这样的文件或目录”错误。


@singlenegationelimination 说


...这不是便携式的,标准不支持它。


ISO C标准可能未指定在其下编译或运行程序的系统的所有详细信息。这并不意味着它们不受支持,只是该标准并未过多指定C将在其上运行的平台。(在常见的现代系统上,如何解释""和如何<>解释的区别可能源于 POSIX标准。)


@ daniel-paull 说


“ ..”采用相对位置且易碎


脆弱如何?大概对两个文件的搭配敏感。因此,..仅在(包括始终)在包含文件的作者控制其位置时使用“”。


查看完整回答
反对 回复 2019-10-11
  • 3 回答
  • 0 关注
  • 691 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信