是否可以在 C/C++ 中永远不使用标头保护?如果是这样,这种方法有啥优势吗?

Posted

技术标签:

【中文标题】是否可以在 C/C++ 中永远不使用标头保护?如果是这样,这种方法有啥优势吗?【英文标题】:Is it possible to never use header guards in C/C++? If so, does this approach have any advantage?是否可以在 C/C++ 中永远不使用标头保护?如果是这样,这种方法有什么优势吗? 【发布时间】:2021-03-14 08:54:23 【问题描述】:

我最近进入了一个项目,其中禁止使用头部防护,因为它是“糟糕的设计”。自定义类型是前向声明的,并且标头仅包含在 cpp 文件中。

这是我看到的第一个这样做的项目,我发现与它一起工作很不舒服,如果由我决定,我会介绍警卫。

使用它们对我来说一直是一个既定的条件,所以我什至不知道如何反对不使用它们,除了强调它不舒服的事实。该项目显然可以编译,因此在这种情况下它是可行的,但我还有几个问题:

是否还有其他情况会使开发变得不可能? 这种风格有众所周知的好处吗? 是否有已知的开源项目使用这种方法? 您将如何说服项目负责人允许使用警卫?

【问题讨论】:

它给出了“糟糕的设计”的理由是什么? 不,您实际上可以直接键入所有行而无需任何头文件。但这样做没有意义。 如果你遇到过头文件 B 和 C 都包含头文件 A,并且 B 和 C 都需要包含在任何东西(例如源文件或其他头文件)中的情况,那么头文件 A 需要包括后卫。通过仔细的设计,可以避免这种情况 - 但通常这样做的人力(包括在某些标题被意外包含多次时修复问题,或者非常严格地限制标题的内容)超过使用 include 的努力警卫。 至少,通过这种方法,您不会意外地出现循环包含 “禁止使用标头保护,因为它是“糟糕的设计”” 他们有一种非常非正统的 C++ 编写方式,或者在最坏的情况下是无能的。 【参考方案1】:

我猜在其他标头中不包含标头会导致在每个翻译单元(.cpp 文件)中维护标头列表。

如果在一个类中引入了对另一个类的依赖,则每个标题列表都将被更新。同样,为了利用损坏的依赖关系,每个列表也必须更新。

这看起来不像一个“好设计”。

【讨论】:

【参考方案2】:

页眉保护并不是“糟糕的设计”。参考Bjarne Stroustrup和Herb Sutter:

SF.8: Use #include guards for all .h files

我希望看到您的新项目背后的人与 Stroustrup 和 Sutter 争论 C++ 中的“糟糕设计”是什么。

前向声明是一个很好的工具,是的。但肯定不是所有情况的答案。那将如何运作?你只有指针作为类成员?您仔细确保头文件中没有定义任何内容?

【讨论】:

我不会争辩说这种“不包括警卫”的政策应该受到挑战,但不是通过诉诸权威。 Stroustrup 和 Sutter 也犯了很多错误。 我的方法源于对“地方当局”不允许挑战他们的方式的挫败感,对此我在某个主题上以“全球权威”回应。但是,如果提出任何真正的论点,我们可以改为进行技术讨论。感谢您的评论,但我牢记在心。

以上是关于是否可以在 C/C++ 中永远不使用标头保护?如果是这样,这种方法有啥优势吗?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 C 中创建“变量”标头保护名称?

标准标头/库中是不是包含保护?

使用 AJAX GET 方法的 CSRF 令牌保护

是否可以在 URL 本身中传递 HTTP 标头?

使用授权标头重定向到操作

标头保护中的 MYHEADER_HPP 如何与实际文件名“MyHeader.hpp”相关