В 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 ‹ 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 Garbage Collector с 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

Между другото намирам за абсолютно необходимо наличието на събирач на отпадъци в компилатора, но намирам GC на 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 вече не поддържа предварително компилирани заглавки в подвключвания:

Подадена грешка: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52518

person Casey Rodarmor    schedule 07.03.2012
comment
PS Съжалявам момчета. Чувствам се някак виновен, че се оплаках от повреда на добра функция и те отговориха, като премахнаха всички следи от нея от документацията :( - person Casey Rodarmor; 08.03.2012