为什么支持预编译头的编译器通常只允许一个?

时间:2014-10-14 23:46:41

标签: compiler-construction compiler-optimization precompiled-headers

使用多个预编译头文件有潜在的好处。假设存在一个项目,其中有几个标题不经常更改并在许多源代码文件中使用。这些标题倾向于两个簇A和B.当A中的一个标题改变时,A中的其他标题也可能改变,但B中标题改变的概率不受影响,反之亦然。

在这种情况下使用两个预编译头文件可能会有所帮助,但大多数支持预编译头文件的编译器只支持一个预编译头文件。

这是什么原因,为什么会这样?

注意:这个问题不是询问是否存在支持多个预编译头的编译器或如何实现这一点。

问题是询问允许多个预编译头文件在技术上具有挑战性或不切实际的原因。

我感兴趣的具体编译器是gcc和clang编译C ++,但我的期望是不会改变答案。

1 个答案:

答案 0 :(得分:2)

我认为真正的问题是组合数据是由源/头文件中的条件数量所决定的。

大多数头文件都充满了条件。 “预编译”意味着条件已被解决...不幸的是,如果您选择将条件解析为真或假,并且您有20个条件,则可能有~1600万个可能的配置。 (我们甚至不计算是标量的定义,而不是布尔值,或者是参数化的宏)。

如果使用的是需要一个配置,则可以使用一个预编译的头文件。有趣的是,对于个体开发者而言,这似乎很常见,这是“只有一个”的一种解释。但是如果配置变化很快,任何一个都需要大量的预编译头,这有自己的成本(想象“预编译”1600万个预配置的头文件),或者必须按需生成它们(哎呀,这是我们希望的情况避免)。

有人可能会这两种方式。

“预编译”的大部分成本只是处理文本。如果编译器将头文件分解为成功者令牌并存储令牌,则可以在很大程度上避免该文本处理时间,即使每次仍然评估条件。对于执行此操作的C或C ++编译器,我从未见过(但看起来并不是很难)。

另一种可能性是预编译和存储用户实际使用的每个组合,并存储由配置索引的组合。然后查找将很容易找到“正确”的预编译头。我怀疑这对于单个用户来说是最适合的;谁有时间试验数百种配置?

一种遥远的想法是象征性地评估条件。虽然许多条件是独立的,但有些条件控制着其他条件的配置,因此在条件中存在一组复杂的约束......可以预先计算这些组合,然后预先计算可能的配置。在实践中可能会有更少的有用组合。

更实际的可能是隔离相互关联的条件组。从本质上讲,你会得到很多较小的头文件,每个文件都有较少的条件。如果它们足够小,您实际上可以预先计算较小文件的选择空间,然后只需选择正确的文件。您必须将预处理器配置说明附加到每个。

通常最好的解决方案是混合动力车。我希望存储令牌而不是文本,如上所述拆分条件,但是留下一些带有一些未评估条件的文件,实际上被“处理”会产生非常有用的结果。

唉,我必须将这些想法留给其他人实施的热情: - }