2

When I compile a c++ file that includes a precompiled header, everything works as expected

// 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

(! means that gcc found and used the precompiled header)

However, when I put #include < precompiled.h > into header.h, it doesn't work:

// test.c++
#include <header.h>
main() {}

> g++-4.7 --std=c++11 BLAH... test.c++ -H 2>&1 | grep precompiled.h
. precompiled.h

(no ! or x means that gcc failed to find the precompiled header)

What's going on? My understanding was that as long as gcc hit an #include that pointed to a header with a corresponding .gch before any C/C++ tokens, it would use the GCH, which suggests to me that a sub-include should be okay.

Am I mistaken?

Casey Rodarmor
  • 14,878
  • 5
  • 30
  • 33
  • Does `-Winvalid-pch` give any hints? – MSalters Mar 06 '12 at 08:44
  • Did you meet all requirements from [this](http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Precompiled-Headers.html)? Also post the *header.h* – BЈовић Mar 06 '12 at 08:45
  • @MSalters No, I'm using -Winvalid-pch and it doesn't tell me anything. @VJovic Yes, I believe I meet all the requirements. In the second example the first line of header.h is: `#include ` The rest shouldn't be important, right? – Casey Rodarmor Mar 06 '12 at 08:47
  • BTW, precompiled headers are not part of the standard C++ language and compiler specific. There is no guarantee that one precompiled header file may be used in other translation units. – Thomas Matthews Mar 07 '12 at 23:02
  • Good point. I guess this question is entirely GCC specific. – Casey Rodarmor Mar 07 '12 at 23:55

2 Answers2

4

It is a current weakness of GCC (the implementation).

Today, GCC precompiled headers are essentially a memory dump of the compiler's state just after parsing the whole header (PCH uses the Gcc Garbage Collector machinery with GTY annotations inside the compiler's source and gengtype) So to make it work; basically ggc is copying the entire GCC heap [the data inside the compiler] inside your PCH.

For users, it means that the only current way to take profit of PCH is to have exactly one single header (which itself would include several system headers like <stdio.h> in C or <vector> in C++) which is included by all your *.c or *.cc files.

When GCC compiles an #include which cannot be satisfied by a PCH (e.g. because it has some code before it), it just ignores that PCH. In your example, it has already parsed some of header.h before attempting to load the PCH, and it notices that its heap is not empty (some "locations", i.e. source file positions, are already inside), so it cannot use the PCH so skips it.

Diego Novillo and other people at Google are working to improve that in the PPH branch of GCC. I have no idea if their work will be mature enough for GCC 4.8

BTW, I find absolutely essential the presence of a garbage collector inside a compiler, but I find GCC's GC very poor... (Most GCC contributors disagree with my position).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

This turned out to be a bug in the documentation. Gcc no longer supports precompiled headers in subincludes:

Bug filed: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52518

Casey Rodarmor
  • 14,878
  • 5
  • 30
  • 33
  • 1
    PS Sorry guys. I feel kind of guilty that I complained about a good feature being broken, and they responded by removing all traces of it from the documentation :( – Casey Rodarmor Mar 08 '12 at 08:52