Можно ли в 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
// 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 не согласны с моей позицией).