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

Когда я компилирую файл С++, который включает предварительно скомпилированный заголовок, все работает так, как ожидалось.

// 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 ‹ precompiled.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

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

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

Я ошибаюсь?


person Casey Rodarmor    schedule 06.03.2012    source источник
comment
-Winvalid-pch подсказывает?   -  person MSalters    schedule 06.03.2012
comment
Вы выполнили все требования из этого? Также опубликуйте header.h   -  person BЈовић    schedule 06.03.2012
comment
@MSalters Нет, я использую -Winvalid-pch, и это мне ничего не говорит. @VJovic Да, я считаю, что отвечаю всем требованиям. Во втором примере первая строка header.h: #include <precompiled.h> Остальное не должно быть важным, верно?   -  person Casey Rodarmor    schedule 06.03.2012
comment
Кстати, предварительно скомпилированные заголовки не являются частью стандартного языка C++ и специфичны для компилятора. Нет никакой гарантии, что один предварительно скомпилированный заголовочный файл может быть использован в других единицах перевода.   -  person Thomas Matthews    schedule 08.03.2012
comment
Хорошая точка зрения. Я предполагаю, что этот вопрос полностью специфичен для GCC.   -  person Casey Rodarmor    schedule 08.03.2012


Ответы (2)


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

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

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

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

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

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

person Basile Starynkevitch    schedule 06.03.2012
comment
Таким образом, несмотря на то, что во втором примере #include <precompiled.h> является самой первой строкой в ​​header.h, он все равно будет пропускать PCH? - person Casey Rodarmor; 07.03.2012
comment
Я только что попробовал примеры, которые я дал в gcc 4.2, и он находит и использует предварительно скомпилированный заголовок, я думаю, что это ошибка в gcc 4.7 (которая, честно говоря, все еще находится в бета-версии). - person Casey Rodarmor; 07.03.2012
comment
Я предполагаю, что дамп данных является причиной того, что он может использовать только один PCH на единицу перевода? - person Anonymous Penguin; 13.02.2015

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

Сообщено об ошибке: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52518

person Casey Rodarmor    schedule 07.03.2012
comment
P.S. Извините, ребята. Я чувствую себя виноватым из-за того, что пожаловался на неработающую хорошую функцию, а они в ответ удалили все ее следы из документации :( - person Casey Rodarmor; 08.03.2012