Можно ли в GCC включать предварительно скомпилированные заголовки из других заголовков?

Когда я компилирую файл 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 в 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

(нет! или x означает, что gcc не удалось найти предварительно скомпилированный заголовок)

В чем дело? Насколько я понимаю, до тех пор, пока gcc попадет в #include, который указывает на заголовок с соответствующим.gch перед любыми токенами C/C++, он будет использовать GCH, что подсказывает мне, что с подключением должно быть все в порядке.

Я ошибаюсь?

2 ответа

Решение

Это оказалось ошибкой в ​​документации. Gcc больше не поддерживает предварительно скомпилированные заголовки в подлинку:

Ошибка подана: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52518

Это текущая слабость GCC (реализация).

Сегодня предварительно скомпилированные заголовки GCC - это, по сути, дамп памяти состояния компилятора сразу после синтаксического анализа всего заголовка (PCH использует механизм сборщика мусора Gcc с аннотациями GTY внутри источника компилятора и gengtype) Так, чтобы это работало; в основном, ggc копирует всю кучу GCC [данные внутри компилятора] внутри вашего PCH.

Для пользователей это означает, что единственный текущий способ получить прибыль от PCH - это иметь ровно один единственный заголовок (который сам включает несколько системных заголовков, таких как <stdio.h> в С или <vector> в C++), который включен всеми вашими *.c или же *.cc файлы.

Когда GCC компилирует #include который не может быть удовлетворен PCH (например, потому что у него есть некоторый код перед ним), он просто игнорирует этот PCH. В вашем примере он уже проанализировал некоторые из header.h перед попыткой загрузить PCH, и он замечает, что его куча не пуста (некоторые "местоположения", то есть позиции исходного файла уже находятся внутри), поэтому он не может использовать PCH, поэтому пропускает его.

Диего Новилло и другие сотрудники Google работают над улучшением этого в филиале GCC в PPH. Я понятия не имею, будет ли их работа достаточно зрелой для GCC 4.8

Кстати, я считаю абсолютно необходимым присутствие сборщика мусора внутри компилятора, но я считаю, что GC GCC очень плохой... (Большинство участников GCC не согласны с моей позицией).

Другие вопросы по тегам