在GCC中,可以从其他头文件中包含预编译的头文件吗

In GCC, can precompiled headers be included from other headers?

本文关键字:文件 包含预 编译 GCC 其他      更新时间:2023-10-16

当我编译一个包含预编译头的c++文件时,一切都能像预期的一样工作

// test.c++
#include <precompiled.h>
#include <header.h>
main() {}
> g++-4.7 --std=c++11 BLAH... test.c++ -H 2>&1 | grep precompiled.h
! precompiled.h.gch

(!表示gcc找到并使用了预编译头)

然而,当我把#include<预编译.h>到header.h中,它不起作用:

// test.c++
#include <header.h>
main() {}
> g++-4.7 --std=c++11 BLAH... test.c++ -H 2>&1 | grep precompiled.h
. precompiled.h

(no!或x表示gcc找不到预编译头)

怎么回事?我的理解是,只要gcc在任何C/C++标记之前命中一个指向带有相应.gch的标头的#include,它就会使用gch,这对我来说表明子include应该是可以的。

我错了吗?

这是GCC(实现)目前的一个弱点。

如今,GCC预编译的头本质上是在解析完整个头之后编译器状态的内存转储(PCH使用GCC垃圾回收器机制,在编译器的源代码和gengtype中带有GTY注释)。因此,为了使其工作;基本上ggc是在PCH中复制整个GCC堆[编译器中的数据]。

对于用户来说,这意味着目前从PCH中获利的唯一方法是只有一个单独的标头(它本身会包括几个系统标头,如C中的<stdio.h>或C++中的<vector>),它包含在所有的*.c*.cc文件中。

当GCC编译一个PCH无法满足的#include时(例如,因为它在之前有一些代码),它只会忽略该PCH。在您的示例中,它在尝试加载PCH之前已经解析了一些header.h,并且它注意到它的堆不是空的(一些"位置",即源文件位置,已经在里面了),所以它不能使用PCH,所以跳过它。

Diego Novillo和谷歌的其他人正在GCC的PPH分支中努力改进这一点。我不知道他们的工作是否足够成熟,适用于GCC 4.8

顺便说一句,我发现编译器中存在垃圾收集器是绝对必要的,但我发现GCC的GC非常差。。。(大多数GCC贡献者不同意我的立场)。

这是文档中的一个错误。Gcc不再支持子包中的预编译头:

提交的Bug:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52518