包括声明之外包括警卫
Posted
技术标签:
【中文标题】包括声明之外包括警卫【英文标题】:Include statements outside include guards 【发布时间】:2015-04-29 20:43:26 【问题描述】:我最近开始在一个项目中遇到这个问题:
#include <string.h> // includes before include guards
#include "whatever.h"
#ifndef CLASSNAME_H // header guards
#define CLASSNAME_H
// The code
#endif
我的问题:考虑到所有(包含的)头文件都是以相同的样式编写的:这会导致问题(循环引用等)。并且:有什么(好的)理由这样做吗?
【问题讨论】:
1) 包括警卫很好。 2)我希望只在标题中看到它们,并且我希望它们包装 ENTIRE 标题。 3) 我会不使用包含代码的守卫。而且我不喜欢在标题中包含代码。 4)您的标题可以(并且应该)#include 任何它需要的东西。您可以放心地假设其他标头都应该有自己的包含守卫。 好吧,把你的整个头球放在后卫里面也没什么坏处。但是您包含的其他标头应该已经使用过一次“守卫”#ifndef 或#pragma。您几乎总是可以依靠遵循此约定的系统标头。 在包含防护之前没有理由包含包含。但是,如果 '潜在地,在包含防护之外有#include
可能会导致循环引用等。如果其他文件得到适当的保护,就不会有问题。如果其他文件都这样写,可能会有问题。
不,据我所知,没有充分的理由使用包含保护之外的 #include
行编写代码。
包含保护应该围绕标题的全部内容;我想不出有什么例外(当标头保护首先是合适的——C 标头<assert.h>
是一个没有标头保护的好理由)。
【讨论】:
【参考方案2】:只要您没有循环包含(whatever1.h
包括 whatever2.h
其中包括 whatever1.h
),这应该不是问题,因为代码本身仍然受到保护,不会被多次包含。
然而,它几乎肯定会影响编译时间(多少取决于项目大小),原因有两个:
-
现代编译器通常检测“经典”包含守卫,然后忽略该文件的任何进一步
#includes
(就像#pragma once
)。您显示的结构阻止了这种优化。
每个编译单元变得更大,因为每个文件将被更频繁地包含 - 就在预处理器再次删除所有非活动块之前。
无论如何,我想不出这样的结构会有什么好处。也许这是一些奇怪的历史原因的结果,比如在标准 C++ 时代之前在您的代码库中使用了一些晦涩的分析工具。
【讨论】:
以上是关于包括声明之外包括警卫的主要内容,如果未能解决你的问题,请参考以下文章