未使用的包含在C/ c++中是有害的

Are unused includes harmful in C/C++?

本文关键字:c++ 包含 未使用      更新时间:2023-10-16

未使用的include的负面后果是什么?

我知道它们会导致二进制大小的增加(或者它们会吗?),还有别的吗?

  • 增加编译时间(潜在的严重问题)
  • 污染全局命名空间
  • 预处理器名称可能冲突。
  • 如果第三方库中包含了未使用的头文件,可能会使这些库不必要地作为依赖项进行维护。

它们不一定会增加二进制文件的大小,但会增加编译时间。

主要问题是杂乱。以下是杂乱表现的三个主要方面:

  1. 视觉污染;当你试图找出你需要的其他包含时。

  2. 逻辑污染;它更有可能有函数冲突,更多的编译时间(它可能对几个包含来说真的很小,但如果它成为不清理不需要的包含的"策略",它可能成为一个重大障碍)。

  3. 依赖不透明;因为有更多的头文件要分析,所以很难确定代码中的依赖周期。当你的代码库增长到超过业余水平的重要水平时,了解代码中的依赖关系是至关重要的。

一般来说,是的,它确实会引起一些问题。从逻辑上讲,如果你不需要它,那就不要包含它。

  • 任何在头文件中声明为外部并在源文件中定义的单例都将包含在您的程序中。这显然会增加内存使用,并可能导致更频繁地访问他们的页面文件,从而导致性能开销(现在不是太大的问题,因为单例通常小到中等大小,因为我认识的大多数人都有6+ GB的RAM)。

  • 编译时间增加了,对于经常编译的大型商业项目,这可能会导致金钱损失。它可能只会增加你的总时间几秒钟,但乘以几百个编译器,你可能需要测试和调试,你已经浪费了大量的时间,从而转化为利润损失。

  • 头文件越多,就越有可能与程序中定义的宏或其他头文件发生冲突。这可以通过正确使用名称空间来避免,但是查找它仍然很麻烦。

  • 导致代码膨胀(更长的文件,因此更多的阅读),并且可以主要增加您在IDE的自动完成工具中找到的结果数量(有些人非常反对这些工具,但它们确实在一定程度上提高了生产力)。

  • 你可能不小心将其他外部库链接到你的程序中,甚至不知道它。

  • 你这样做可能会无意中导致世界末日。

我假设这些头文件都可以被认为是"真诚的",也就是说,它们不是为了破坏你的代码而写的。

  • 它通常会减慢编译(预编译的头文件可以缓解这一点)

  • 它暗示了不存在的依赖(这是语义错误,不是实际错误)

  • 宏将污染您的代码(通过使用与名称空间类似的名称作为宏的前缀来缓解,例如在BOOST_FOREACH而不是FOREACH)

  • 头文件可能暗示指向另一个库的链接。在某些情况下,未使用的头文件可能会要求链接器将您的代码与外部库链接(参见MSCV的#pragma注释(lib, "))。我相信一个好的链接器不会保留未使用库的引用(IIRC, MSVC的链接器不会保留未使用库的引用)。

  • 删除标头可以减少意外bug的来源。如果你不相信头文件(有些编码员比其他人更好…),那么删除它就会消除风险(你不会喜欢包括头文件,改变它之后的所有内容的结构对齐:生成的bug是…)照明…)。

  • 和头文件的static变量声明会污染你的代码。每个静态变量声明都会导致在编译后的源代码中声明一个全局变量

  • C符号名会污染你的代码。头文件中的声明将污染您的全局或结构命名空间(更可能的是,两者都有,因为结构通常被类型定义以将其类型带入全局命名空间)。这可以通过库在其符号前加上某种"命名空间名称"来缓解,例如SDL的SDL_CreateMutex

  • 非命名空间 c++符号名会污染你的代码。出于同样的原因。同样的道理也适用于错误使用using namespace语句的头。现在,正确的c++代码将命名它的符号。是的,这意味着你通常不应该相信在全局命名空间中声明其符号的c++头文件…

是否增加二进制大小实际上取决于其中的内容。

主要的副作用可能是对编译速度的负面影响。同样,影响有多大取决于其中的内容,数量以及是否包含其他标题。

首先,只留下会延长的编译时间,并增加不必要的编译依赖项。

它们代表笨拙的设计。

如果你不确定包含什么,不包含什么,这表明开发人员不知道他在做什么。

Include文件意味着只在需要时才被包含。随着计算机内存和速度的突飞猛进,这可能不是什么大问题,但它曾经可能是。

如果一个包含是不需要的,但无论如何都包含了,我建议在它旁边放一个注释,说明你为什么包含它。如果新开发人员接触到您的代码,如果您的方法正确,他将非常欣赏您。

include表示您正在添加更多声明。因此,当您编写自己的全局函数时,需要注意该函数是否已在包含的头文件中声明过。

交货。如果您编写自己的类auto_ptr{}而不包含"memory",则可以正常工作。但是当你包含内存时,编译器给出错误,因为它已经在内存头文件中声明了

是的,它们可以增加二进制大小,因为外部未使用的变量。

//---- in unused includes ----
extern int /* or a big class */ unused_var;
//---- in third party library ----
int unused_var = 13;