C++ 的有效用途除此之外,还包括守卫,那么,包括守卫?

发布于 2024-10-15 12:22:08 字数 621 浏览 3 评论 0原文

这个问题是讨论 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

So要识趣 2024-10-22 12:22:08

我认为这个问题本身就有缺陷。术语“包含防护”指的是#define,并在防止多重包含的特定使用中检查#define,这与说这是唯一的用途。

现在更一般地说,定义和条件编译可用于其他用途,例如编写依赖于平台的代码,并且仅在某些情况下才会编译...

无论是 FOO_H 还是 FOO_H_INCLUDED 更好,我总是说后者最具表现力,然后我会返回到 vi 并在下一个 vi 中输入 FOO_H code>foo.h 标头。再次,正如我在对另一个问题的评论中提到的,您逐渐习惯了这种模式:

#ifndef XXXXXXXXX
#define XXXXXXXXX

#endif

作为文件中的前两行和最后一行,您最终会注意到。直到你重复使用同一个名字,它才会反击……

I think the question is flawed in itself. The term include guards refers to #defines 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 or FOO_H_INCLUDED is better, I will always say that the later is the most expressive, and then I will go back to vi and type FOO_H in my next foo.h header. Again, as I mentioned in a comment on the other question, you grow used to the pattern:

#ifndef XXXXXXXXX
#define XXXXXXXXX

#endif

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...

顾铮苏瑾 2024-10-22 12:22:08

有时,我用它来“实现”头文件。守卫的实际命名方案可能有所不同。

#ifndef FOO_IMPL_H
#define FOO_IMPL_H

#ifndef FOO_H
#error Don't include this directly
#endif

// Ugly implementation of the stuff in foo.h, with an uncountable
// number of template and typename keywords

#endif 

Sometimes, I use this for "implementation" header files. Actual naming scheme for guards may differ.

#ifndef FOO_IMPL_H
#define FOO_IMPL_H

#ifndef FOO_H
#error Don't include this directly
#endif

// Ugly implementation of the stuff in foo.h, with an uncountable
// number of template and typename keywords

#endif 
迷途知返 2024-10-22 12:22:08

在我看来,包含守卫应该是包含守卫,仅此而已。如果你想要条件编译,我会定义别的东西。如果您在代码中乱扔 #if Defined(FOO_H) ,我想人们会觉得这很奇怪,因为 _H 通常表示包含保护。

我能想到的一件事是检查该文件是否已包含(废话!),这样您就不必自己包含该文件。我不确定与前向声明或 #pragma Once 相比这是否会加快编译速度

In main.cpp:

#include "bar.h" // comment this line to see the difference
#include "foo.h"

int main()
{
    return 0;
}

In bar.h:

#ifndef BAR_H
#define BAR_H

class BarClass
{
};

#endif

In foo.h:

#ifndef FOO_H
#define FOO_H

#if !defined(BAR_H)
#error bar h was not included // forgot how to do compiler warnings...
#include "bar.h" // we should include the file
#else
#error bar h was included // same thing, should be changed to warning
#endif

// do something with BarClass

#endif 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:

#include "bar.h" // comment this line to see the difference
#include "foo.h"

int main()
{
    return 0;
}

In bar.h:

#ifndef BAR_H
#define BAR_H

class BarClass
{
};

#endif

In foo.h:

#ifndef FOO_H
#define FOO_H

#if !defined(BAR_H)
#error bar h was not included // forgot how to do compiler warnings...
#include "bar.h" // we should include the file
#else
#error bar h was included // same thing, should be changed to warning
#endif

// do something with BarClass

#endif FOO_H
岁月如刀 2024-10-22 12:22:08

我认为条件编译是一个很好的理由,在这种情况下,将其命名为 FOO_H_INCLUDED 之类的名称会更清晰。

我在这里只看到一种非常狭窄的用途,以避免在您只需要前向声明时包含标头,但如果之前已包含标头则希望跳过前向声明。

然而,这并不是当今编译 C++ 的瓶颈,并且始终具有前向声明或始终包含标头所带来的额外混乱是不值得的。

即使您需要大量(我的意思是数百到数千行这些前向声明),这样它才变得值得,您最好使用类似于的专用标头,而不是在多个中维护它地方。

I'd think conditional compilation would be a good reason, in which case naming it something like FOO_H_INCLUDED would be clearer.

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.

烟织青萝梦 2024-10-22 12:22:08

对于重新利用:除非文件的全部内容都被 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 called uppercase.h which uses UPPERCASE_H as an include guard, then that could conceivably clash with someone's rot13.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文