Comments 31
Спасибо, за интересную статью. Вот именно из-за отсутствия объяснения подобных вещей я и не освоил C++ в свое время, потому что всех книгах пишут КАК надо написать, а не ПОЧЕМУ так надо написать. А сейчас и не сильно нужно. Жду еще интересных статей о раскрытии магии С++.
+9
stdafx.h это не С++ — это привет от microsoft и его жутко настраиваемого монстра в лице студии
+4
А почему Вы думаете что только в MS VS это есть? К примеру в 3.20 Using Precompiled Headers или я Вас неправильно понял?
+2
Нет, есть конечно, но только VS генерирует подобный файл при создании проекта.
-2
И правильно делает! ;) Это очень удобная технология и ее знать надо!
0
Делает это без объяснений и сильно преждевременно, вот и возникают у новичков траблы с компиляцией и не пониманием нафиг это чудо-юдо нужно
0
Спасибо за отличный ликбез.
+3
Кроме VS еще кто-то умеет такое?
+3
gcc умеет. Если собирать хедеры как-нить так gcc -с xxx.h, то получится на выходе xxx.h.gch, его потом думаю можно аналогично использовать. Но мне всетаки кажется это преждевременной оптимизацией, которая все запутывает.
+5
clang умеет: clang.llvm.org/docs/PCHInternals.html
+2
Спасибо за статью. Хотелось бы уточнить несколько вопросов касательно темы:
- Как по вашему, допустимо ли в stdafx.h использование конструкции using namespace?
- Как насчет запихнуть туда (в stdafx.h) набор любимых макросов?
- Нужно ли делать include guard, для stdafx.h?
+1
Как по-вашему, допустимо ли в stdafx.h использование конструкции using namespace?
Смотря какой проект. В большом думаю не стоит. В маленьких и средних, я думаю не будет беды в использовании using namespace для std и т.п. Вообще это на усмотрение разработчиков.
Как насчет запихнуть туда (в stdafx.h) набор любимых макросов?
Если они везде нужны, то можно и полезно. Например, у нас в stdafx.h был свой макрос для подавления предупреждений о неиспользуемых переменных. Потом он превратился в функцию, но смысл не поменялся. Функция также живёт в stdafx.h, так как используется повсеместно:
// UNREFERENCED_PARAMETER от Герб Саттера
template void PVS_UNREFERENCED_PARAMETER( const T& ) { }
Нужно ли делать include guard, для stdafx.h?
Как-то никогда не задумывался над этим вопросом. По идеи, два раза stdafx.h включаться не должен. Он ведь включается один раз в начале *.c/*.cpp файлов. У нас на всякий случай написано "#pragma once". Думаю, лишняя защита не повредит.
+1
В студии есть штатный макрос DBG_UNREFERENCED_LOCAL_VARIABLE(var) и UNREFERENCED_PARAMETER
Мы его вставляли в паре сотен мест, когда убирали варнинги 4 уровня в проекта в пару миллионов строк :)
Мы его вставляли в паре сотен мест, когда убирали варнинги 4 уровня в проекта в пару миллионов строк :)
0
GCC и clang ругаются на "#pragma once" в хедере, если он помечен как используемый для precompiled
Так что лучше делать так:
Так что лучше делать так:
// pragma once in precompiled header causing a warning in non-MSVC compilers
#ifdef _MSC_VER
#pragma once
#endif // _MSC_VER
0
Как по вашему, допустимо ли в stdafx.h использование конструкции using namespace?
Использование using namespace в любом *.h файле ведет к приятным часам компиляции.
У вас есть
qq::foo; ww::foo;
потом вы написали using namespace qq;
using namespace ww;
а используете просто как foo.Какой из foo должен выбрать компилятор?
0
Помню у нас большой проект даже с precompiled headers собирался 45 минут, и я вот тут подумал: а как в Qt? Что там делают, чтобы огромные проекты не собирались неделями?
+2
А там все хорошо, вы точно также можете использовать precompiled headers.
0
А почему они должны собираться неделями? Что вы такое собираете?
У нас в проекте Chromium для тестов собирается с особыми ключами, там порядка десяти тысяч файлов, сборка с нуля занимает порядка 10 минут, есть сколько-то precompiled headers в third party code, но с ними собирается меньше одного процента файлов.
Правда есть одно но: в качестве основной платформы для разработки у нас Linux, а не Windows, в частности потому, что Windows какими примочками не натирай — сборка занимает много больше, чем под Linux. Этак разика в три, если не в пять. Хотя машинки идентичны (Dual Xeon CPU E5-2690, 64GiB RAM).
У нас в проекте Chromium для тестов собирается с особыми ключами, там порядка десяти тысяч файлов, сборка с нуля занимает порядка 10 минут, есть сколько-то precompiled headers в third party code, но с ними собирается меньше одного процента файлов.
Правда есть одно но: в качестве основной платформы для разработки у нас Linux, а не Windows, в частности потому, что Windows какими примочками не натирай — сборка занимает много больше, чем под Linux. Этак разика в три, если не в пять. Хотя машинки идентичны (Dual Xeon CPU E5-2690, 64GiB RAM).
+1
Странно, что под винду ощутимо дольше сборка. Насколько помню, у Chromium просто гигантская кодовая база, если это все собирается 10 мин — просто чудо)
P.S. я говорил про проект, на движке которого, фактически, работали первые версии ДубльГис, в этом внутреннем продукте делалось все: рисование карты, внесение фирм, рекламы, ведение рубрикатора, полный технологический цикл в общем, просто это все было разбито на проекты. Классов примерно 3000.
P.S. я говорил про проект, на движке которого, фактически, работали первые версии ДубльГис, в этом внутреннем продукте делалось все: рисование карты, внесение фирм, рекламы, ведение рубрикатора, полный технологический цикл в общем, просто это все было разбито на проекты. Классов примерно 3000.
0
Не странно. Собираем clang под Windows и под RedHat на одинаковых машинах — под виндой действительно дольше раза в два-три.
По поверью, дело в реализации дисковой подсистемы, которая в Windows (изначально интерактивной ОС) оптимизирована под latency, а в Linux (изначально пакетной ОС) — под throughput.
По поверью, дело в реализации дисковой подсистемы, которая в Windows (изначально интерактивной ОС) оптимизирована под latency, а в Linux (изначально пакетной ОС) — под throughput.
0
Это не чудо, это норма. А вот тормоза под Windows — это беда. Когда Chrome собирается под Linux, то почти всё время все 32 процессора заняты на 95-99%. Когда же Chrome собирается под Windows, то часто работой загружены 3-5 процессоров, а остальные простаивают. Бог знает чем это чудо в этот момент занято: компиляторов в обоих случаях запущены десятки (ninja всё-таки и там и там), только под Windows они периодически останавливаются «покурить».
0
Свершилось: PVS-Studio для Linux.
0
Отличный ликбез. уверен, что он будет полезен не только новичкам, но и более матерым программистам!
+1
1. Отличный ликбез.
2. Замеры скорости сборки с и без Precompiled Headers будут?
3.
Отличный совет тем, кому потом программу портировать на другую платформу/ос/компилятор…
4.
Очень громкое заявление, которое ничем не подкреплено. Если разместить проект в оперативной памяти (RAMDisk), то чтение будет очень быстрым. Тем более, что в файл нужно подставить только один инлюд, а с Precompiled Headers будет вставлено очень много мегабайт текста, который нужно еще скомпилировать.
5. При наличие большого кол-во проблем, связанных с Precompiled Headers возникает вопрос об их целесобразности. Ну да, они дают N% ускорения, но есть же и другие способы повысить скорость компиляции, которые дадут больше ускорения. Например, если если система сборки cmake, то вместо того чтобы генерировать «MS Solution» можно сгенерировать ninja файл и собрать 1.5 раза*(из личного опыта на большом проекте) быстрее. Разместите файлы на RAMDisk, и вот еще прибавка к скорости, не меняя исходников.
6. А если нужно провести рефакторин, то нужно планировать и рефакторинг хидеров, так как они будут либо часто пересобираться либо вообще не нужны. Что опять же усложнит процесс разработки.
итого: я не против Precompiled Headers, я призываю подумать 100500 раз и доказать себе, что оно нужно в конкретном проекте и без него совсем ни как.
2. Замеры скорости сборки с и без Precompiled Headers будут?
3.
Идём на вкладку настроек «Advanced». Выбираем все конфигурации. В поле «Forced Included File» пишем:
StdAfx.h;%(ForcedIncludeFiles)
Теперь «stdafx.h» автоматически будет включаться в начало ВСЕХ компилируемых файлов. PROFIT!
Больше не потребуется писать #include «stdafx.h» в начале всех *.c/*.cpp файлов. Компилятор сделает это сам
Отличный совет тем, кому потом программу портировать на другую платформу/ос/компилятор…
4.
Выигрыш от того, что при препроцессировании не надо читать множество файлов и вставлять их друг друга намного больше, чем потери на синтаксический анализ лишних фрагментов кода.
Очень громкое заявление, которое ничем не подкреплено. Если разместить проект в оперативной памяти (RAMDisk), то чтение будет очень быстрым. Тем более, что в файл нужно подставить только один инлюд, а с Precompiled Headers будет вставлено очень много мегабайт текста, который нужно еще скомпилировать.
5. При наличие большого кол-во проблем, связанных с Precompiled Headers возникает вопрос об их целесобразности. Ну да, они дают N% ускорения, но есть же и другие способы повысить скорость компиляции, которые дадут больше ускорения. Например, если если система сборки cmake, то вместо того чтобы генерировать «MS Solution» можно сгенерировать ninja файл и собрать 1.5 раза*(из личного опыта на большом проекте) быстрее. Разместите файлы на RAMDisk, и вот еще прибавка к скорости, не меняя исходников.
6. А если нужно провести рефакторин, то нужно планировать и рефакторинг хидеров, так как они будут либо часто пересобираться либо вообще не нужны. Что опять же усложнит процесс разработки.
итого: я не против Precompiled Headers, я призываю подумать 100500 раз и доказать себе, что оно нужно в конкретном проекте и без него совсем ни как.
+7
Хм, а есть замеры скорости сборки с RAMDisk?
Из личного опыта: на не очень маленьком проекте с использованием boost, который компилировался около 5 минут, перенос проекта с с boost-ом и другими библиотеками на RamDisk практически не ускорил проект (ускорил, но на еле-еле). О таком же поведении когда-то упоминали на StackOverflow… Операционные системы отлично кэшируют. Ускорял компиляцию другими методами
Из личного опыта: на не очень маленьком проекте с использованием boost, который компилировался около 5 минут, перенос проекта с с boost-ом и другими библиотеками на RamDisk практически не ускорил проект (ускорил, но на еле-еле). О таком же поведении когда-то упоминали на StackOverflow… Операционные системы отлично кэшируют. Ускорял компиляцию другими методами
0
Статья же была на эту тему: Оптимизация сборки крупного проекта
0
Спасибо, отличная статья; добавлю в must read для своих подопечных учеников.
0
Спасибо, интересно.
0
Sign up to leave a comment.
Для новичков про stdafx.h