c语言关键字include的使用(CCinclude方面不要花哨)
更多C语言学习内容,请私信 我 “代码” 获取
在不得不清理一些不寻常的#include技术之后,我将就如何不使用#include以及如何使用它提出一些建议。
特定的代码库相对较旧,有其瑕疵和特点。换句话说,这是多年来在历史上或歇斯底里地发展的遗留代码。
在一些枚举和typedef之后,有问题的标题有很多包括 - 超过20个 ,在对源代码进行一些分析之后,出现了以下图片:该项目包含大约300个源文件和相应的头文件,分布在少数目录中。
project_root
utilities
| include
| | some_util.h
| | someother_util.h
| | ...
| some_util.cpp
| someother_util.cpp
| utilities.h
one_directory
| ...
another_directory
| ...
stdafx.h
main.cpp
请注意utilities.h标题 - 它是包含许多内容的标题。它包括一切在公用库/ include目录。其他目录具有类似的结构,包括“主标题”,它将#include相应include目录中的所有内容。还有utilities.h标题。
所有源文件基本上都是#include stdafx.h及其相应的目录主标题。只是偶尔,如果需要来自除实用程序之外的其他目录的东西,它们也会#include该目录的主标题。由于单个类头只是#included只有一次,在主头中,他们甚至不需要包含警卫。只有主标题有一个#pragma once。
更多C语言学习内容,请私信 我 “代码” 获取
这有什么问题?乍一看,这听起来非常方便。如果我们在其中一个目录中添加一个新类,只需将标题#include到主标题中,我们就可以在目录中的任何地方使用它。我们也可以在新类中使用该目录中的所有内容,因为我们只在其源代码中包含了主标头。
但是,这种技术会带来许多问题。我不会进入(不一致)使用单独的“包含”目录,因为这主要是品味和惯例的问题。#include "../../utilities/include/some_util.h清理时打字很多东西。
它很脆弱
想象一下,我们添加了一个新的类定义,它取决于主标题末尾的#included标头。我们不能简单地#include我们新类的标题中的其他标题,因为它没有包含保护。它也会打破上述模式。相反,我们必须#include主标题中的新标题低于它所依赖的标题。
然后我们在主标题的顶部更改另一个#include 类依赖于新标题。这是一个问题 - 我们现在必须在所有#include 周围移动,直到再次正确地排序依赖关系。也许我们在这个过程中引入了一些前向声明来打破已经出现的循环依赖。整个过程不必要地繁琐。不,仅包括警卫无法解决它,我们仍然需要在主标题中订购我们的#includes。
它严重夸大了编译时间。
使用上面的模式,每个源#includes主标头,并通过目录中的所有其他标头。此外,其中一个#include实用工具的主标头和至少一个其他主标头的可能性非常大。底线是每个源文件#include包含项目中的每个标头。并且预编译头#include主标头之一并没有什么区别。
所有这些头文件都包含数千行代码,必须进行解析和编译,即使源文件中定义的函数不使用这些类。通过用实际需要的#include替换三个或四个主标题,我们可以将项目的完整构建时间从15分钟减少到4分钟以下。仍有很大的潜力可以进一步减少这种情况。
在这种情况下几乎没有增量构建
想象一下,我们在这个项目中改变了一些代码。除非更改仅限于源文件,否则更改将影响每个翻译单元。它不会影响行为或生成的代码,但由于我们触及的标题在任何地方都是传递的#include ,构建系统将重新编译所有内容。15分钟编译时间用于在一个地方使用的类的另一个属性。那是需要很多咖啡。
结论
更多C语言学习内容,请私信 我 “代码” 获取
在#include方面不要花哨。使用已被证明运行良好的通用模式:
,
- *使用包含在每一个头文件保护
- *#包括仅包含您使用定义标题
- *#包括所有包含您使用定义标题-不依赖于传递#包括
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com