C++ 的有效用途除此之外,还包括守卫,那么,包括守卫?
这个问题是讨论 C++ 包含防护的命名约定的几个问题之一。提出这个问题的人认为这个命名约定:
#ifndef FOO_H
#define FOO_H
// ...
#endif
单独来看有点不直观(FOO_H
是什么意思?),我倾向于同意。
其他人则表示,除非需要添加更多内容来更好地避免碰撞(例如 PROJECTNAME_FOO_H_SDFFGH69876GF
),FOO_H
这个名称就很好,因为从上下文中可以清楚地看出其目的是什么(也就是说,它位于同名文件的开头,很明显它是一个包含防护)。
如果拥有 FOO_H
的唯一目的是防止多重包含,我可以购买这个,但是否存在我希望在文件中其他地方拥有 FOO_H
的情况?我认为条件编译是一个很好的理由,在这种情况下,将其命名为 FOO_H_INCLUDED
会更清晰。
是否有与此类似的直接用途,或者我应该避免重新利用包含防护?
This question is one of several that discuss naming conventions for C++ include guards. The person asking that question thinks that this naming convention:
#ifndef FOO_H
#define FOO_H
// ...
#endif
is a bit non-intuitive when taken by itself (what does FOO_H
mean?) and I tend to agree.
Others say that, barring the need to add more stuff for better collision avoidance (like PROJECTNAME_FOO_H_SDFFGH69876GF
), the name FOO_H
is just fine because it's clear from its context what its purpose is (namely, it's at the beginning of the files of the same name and it's clear that it's an include guard).
I could buy this if the only purpose of having FOO_H
would be to guard against multiple inclusion, but are there conditions for which I'd want to have FOO_H
elsewhere in the files? I'd think conditional compilation would be a good reason, in which case naming it something like FOO_H_INCLUDED
would be clearer.
Are there straightfoward uses akin to this, or should I avoid repurposing the include guards?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为这个问题本身就有缺陷。术语“包含防护”指的是
#define
,并在防止多重包含的特定使用中检查#define
,这与说这是唯一的用途。现在更一般地说,定义和条件编译可用于其他用途,例如编写依赖于平台的代码,并且仅在某些情况下才会编译...
无论是
FOO_H
还是FOO_H_INCLUDED
更好,我总是说后者最具表现力,然后我会返回到vi
并在下一个vi 中输入
标头。再次,正如我在对另一个问题的评论中提到的,您逐渐习惯了这种模式:FOO_H
code>foo.h作为文件中的前两行和最后一行,您最终会注意到。直到你重复使用同一个名字,它才会反击……
I think the question is flawed in itself. The term include guards refers to
#define
s and checks for#defined
in the particular use of guarding against multiple inclusion, which is as much to say that is the only use for that.Now taken a little more generally, defines and conditional compilation can be used for other things, like writing bits of code that are platform dependent and will only get compiled under some circumstances...
Whether
FOO_H
orFOO_H_INCLUDED
is better, I will always say that the later is the most expressive, and then I will go back tovi
and typeFOO_H
in my nextfoo.h
header. Again, as I mentioned in a comment on the other question, you grow used to the pattern:as the first two and last line in a file and you end noticing. That is until it bites back if you have reused the same name...
有时,我用它来“实现”头文件。守卫的实际命名方案可能有所不同。
Sometimes, I use this for "implementation" header files. Actual naming scheme for guards may differ.
在我看来,包含守卫应该是包含守卫,仅此而已。如果你想要条件编译,我会定义别的东西。如果您在代码中乱扔
#if Defined(FOO_H)
,我想人们会觉得这很奇怪,因为_H
通常表示包含保护。我能想到的一件事是检查该文件是否已包含(废话!),这样您就不必自己包含该文件。我不确定与前向声明或 #pragma Once 相比这是否会加快编译速度
In main.cpp:
In bar.h:
In foo.h:
In my opinion, include guards should be include guards and nothing more. If you want conditional compilation, I would define something else. If you were throwing around
#if defined(FOO_H)
in your code, I think people would find this strange since_H
usually indicates an include guard.One thing I can think of though is checking if the file has already been included (duh!) so that you don't have to include the file yourself. I'm not sure if this would speed up compilation or not, in comparison to forward declarations or
#pragma once
In main.cpp:
In bar.h:
In foo.h:
我在这里只看到一种非常狭窄的用途,以避免在您只需要前向声明时包含标头,但如果之前已包含标头则希望跳过前向声明。
然而,这并不是当今编译 C++ 的瓶颈,并且始终具有前向声明或始终包含标头所带来的额外混乱是不值得的。
即使您需要大量(我的意思是数百到数千行这些前向声明),这样它才变得值得,您最好使用类似于的专用标头,而不是在多个中维护它地方。
I only see one very narrow use here to avoid including a header when you only need a forward declaration, but want to skip the forward declarations if the header has previously been included.
However, this is not a bottleneck in compiling C++ today, and the added confusion over either always having the forward declarations or always including the header is not worthwhile.
Even if you needed tons – and I mean hundreds to thousands of lines of these forward declarations – so that it did become worthwhile, you'd be better off with a dedicated header, similar to <iosfwd>, rather than maintaining this in multiple places.
对于重新利用:除非文件的全部内容都被 ifndef/define/endif 包围,否则
FOO_H
并不是真正的文件包含保护,它只是保护部分内容一个文件。所以可能不应该以整个文件命名。递归包含同一文件是可能出现这种情况的一种情况。也就是说,我怀疑即使如此,定义的用途也应该是非常明显的(无论如何,更明显的是,无论你正在做的是什么棘手的事情,都不是简单的包括防护)。无论您在哪里看到 ifndef FOO/define FOO 模式,甚至只是 ifndef FOO / Define 很多东西,一个简单的注释都可以使 FOO 的含义变得明显(如果还不是很明显的话)。
如果问题的任何部分是令牌
FOO_H
是否可能用于其他目的:我猜您是否有一个名为uppercase.h
的文件,它使用UPPERCASE_H
作为包含保护,那么这可能会与某人的rot13.h
发生冲突,其中包含#define UPPERCASE_A ('N')
等。愚蠢的示例,但是如果您在头文件中定义字母的属性,那么认为其中一些字母可能以_H
结尾并不荒谬。更现实的是,我的项目包含在不同目录中具有相同基名的文件。
因此,无论上下文和重新调整用途的问题如何,我都不会使用
FOO_H
作为包含防护。For repurposing: unless the entire contents of the file are surrounded by the ifndef/define/endif, then
FOO_H
isn't really a file include guard, it's only guarding part of a file. So possibly it shouldn't be named after the whole file. Recursive inclusion of the same file is one situation where this can come up.That said, I suspect that even so, it should be pretty obvious what the define is for (anyway, more obvious that whatever tricksy thing it is you're doing that isn't simple include guarding). Anywhere you see the pattern ifndef FOO/define FOO, or even just ifndef FOO / define lots of stuff, a simple comment can make the meaning of FOO obvious if it isn't already.
If any part of the question is whether the token
FOO_H
might ever be used for some other purpose: I guess if you have a file somewhere calleduppercase.h
which usesUPPERCASE_H
as an include guard, then that could conceivably clash with someone'srot13.h
, containing#define UPPERCASE_A ('N')
, etc. Silly example, but if you were defining properties of letters in a header file then it's not ridiculous to think that some of them might end in_H
.More realistically, I've had projects with include files having the same basename in different directories.
So, regardless of the issue of context and repurposing, I wouldn't use
FOO_H
as an include guard.