标头包含优化

Joh*_*ohn 22 c++

是否有一种自动方式来优化C++中头文件的包含,从而提高编译时间?"自动"一词是指工具或程序.是否有可能找到哪些头文件已过时(例如,未使用暴露的功能)?

编辑:让每个包含标题"只包含一次是一件重要的事情,但有没有办法甚至更改文件的内容,以便经常使用的"功能"在特定包含和不常用的功能是在其他包括?我要求太多?不幸的是,我们正在谈论一个包含数千个文件的现有代码库.它可能是我实际要求的重构工具吗?

谢谢.

def*_*ode 18

更新

我认为你真正想要的是"包括你使用的东西",而不是一组最小的标题.IWYU意味着尽可能向前声明,并包含直接声明您使用的符号的标头.你不能盲目地将文件转换为IWYU,因为它可能不再编译.发生这种情况时,您需要找到丢失的标题并添加它.但是,如果每个文件都是IWYU清理,即使您必须偶尔添加标题,您的编译总体上也会更快.更不用说你的标题将更有意义/自我记录.

正如我之前的回答所指出的那样,技术上可以包含比IWYU所需的更少的标题,但这通常是浪费时间.

现在,如果只有一个工具,大多数IWYU重构grunt为你工作:)


我考虑过创建/使用这样的工具一次.我们的想法是使用二进制搜索和重复编译来查找最小的包含集.经过进一步调查,似乎没有用处.

一些问题:

  • 更改包含的头文件可以更改行为,并仍然允许文件进行编译.特别是一个例子,如果你std::swap在一个单独的头文件中定义了自己的.您可以删除该标头,您的代码仍将使用默认std::swap实现进行编译.但是,std::swap可能是:低效,导致运行时错误,或者更糟糕的是产生微妙错误的逻辑.

  • 有时头文件包含作为文档.例如,要使用std::foreach,通常包括<vector>足以使其编译.额外的代码更有意义#include <algorithm>.

  • 编译器或编译器版本之间的最小编译集可能不可移植.std::foreach再次使用该示例,无法保证std::foreach将提供<vector>.

  • 无论如何,最小的包含集合可能不会显着影响编译时间.Visual Studio和gcc支持#pragma once使得重复包含基本上不存在的性能明智.并且至少gcc的预处理器已经过优化,可以非常快速地(尽可能快地#pragma once)处理包括防护装置.

  • 我是`#pragma once`的忠实粉丝 (7认同)
  • 我认为前瞻性宣告也有很大的收获,不包括. (6认同)
  • MSVC和GCC都能够使用常规的"#include"守卫来跳过重复的包含,因此几乎不需要非标准的pragma. (5认同)
  • @TED:人们在`#pragma once`(或任何编译指示)可用之前很长一段时间都在使用`#include`守卫.几年前我参与了一个没有的项目,这真的很痛苦. (2认同)

T.E*_*.D. 6

大多数编译器都对预编译的头文件有某种支持.

删除完全不需要的包含的工具可能很好.您似乎暗示您希望看到一个删除所需包含的包含由其他包含多余的包含.我不会成为狂热的粉丝.有人可以删除另一个冗余包括一天,然后其他一些可怜的懒人将不得不追踪硬盘上某处包含文件的所有缺失符号突然出现在他们身上没有明显的原因.