Я понимаю, что цель прекомпилированного заголовка заключается в ускорении процесса компиляции с использованием объектного файла, который уже был скомпилирован один раз и связать его с фактическим проектом. Но я не понимаю, почему я должен явно применять Visual Studio для использования stdafx.h
(Project Properities -> C/C++ -> Precompiled Headers -> Precompiled Header)? Почему не #include "stdafx.h"
недостаточно?Почему не включает stdafx.h, недостаточно для VisualStudio?
ответ
Предполагается, что так называемый stdafx.h
выглядит как обычный заголовочный файл. В его имени нет ничего особенного. Он не должен автоматически включать предварительно скомпилированные заголовки.
Идея состоит в том, что stdafx.h
будет рассматриваться как обычный заголовочный файл любым другим компилятором и/или когда у вас нет того, что использовать заголовки прекомпиляторов в MSVC.
Это вы, кто должен сказать, компилятор MSVC, что вы на самом деле хотите , чтобы включить скомпилированные заголовки. Именно поэтому у вас есть эта настройка проекта. И только когда вы включаете предварительно скомпилированные заголовки, stdafx.h
получит свою особую роль и получит специальное обращение от компилятора. И это не обязательно stdafx.h
. Вы можете назначить эту специальную роль любому другому заголовку, указав другое имя в настройках проекта.
Фактически, просмотр ссылки на AFX в проекте, который не имеет ничего общего с библиотеками или фреймами, специфичными для Microsoft, будет довольно странным.
Не могли бы вы уточнить, какая именно специальная обработка получает «stdafx.h» из компилятора? Как это отличается от классического процесса компоновки компиляции? –
@ Вакан Танка: Предварительная компиляция заголовка не имеет ничего общего с «связыванием». Это совершенно другой процесс. «Специальное обращение», которое получает «stdafx.h», в основном таково: его содержимое * предварительно скомпилировано * только один раз, а затем используется в прекомпилированной форме. Вот и все. – AnT
«Это вы должны сообщить компилятору MSVC, что вы действительно хотите включить прекомпилированные заголовки». Разве я не сказал это в MSVC, когда я делал «#include» stdafx.h »? –
Почему нет
#include "stdafx.h"
[...] достаточно?
Потому что это стандартная директива препроцессора C++. * Он ничем не отличается от #include <string>
в отношении компилятора. Если вам нужна дополнительная семантика, вы должны сообщить об этом компилятору.
Поскольку, похоже, существует путаница, как Visual Studio реализует прекомпилированные заголовки, вот ссылка на документацию: Creating Precompiled Header Files.
*Имейте в виде, что нет ничего особенного имени "stdafx.h"
, кроме того, что имя заголовка по умолчанию используется для создания РСНЫ.
Согласовано в моих проектах Visual Studio, заголовок PCH даже не называется 'stdafx.h'. Хотя я использую макрос с CMake, который указывает имя заголовка PCH .. – drescherjm
Извините, но я не следую. Какая дополнительная семантика? Компилятор просто заменяет '#include" stdafx.h "' содержимым 'stdafx.h'. С этого момента я могу вызывать функции, объявленные в 'stdafx.h', и компилятор не будет жаловаться. После компиляции файл stdafx.obj связан с моим проектом. Я не вижу необходимости явно указывать что-то еще здесь. –
@WakanTanka: Вы описали ** стандартную ** семантику. Дополнительная семантика заключается в том, что компилятор заменяет директиву '# include' на ** предварительно обработанную ** и ** предварительно скомпилированную ** версию заголовка. Кроме того, файлы заголовков не являются единицами компиляции. Нет файла * stdafx.obj * * (если вы также не указали * * stdafx.cpp * * файл, который вы делаете для PCH). Файл .obj не имеет ничего общего с PCH. – IInspectable
Несложно ли ответить на вопрос, можно ли безопасно использовать предварительно скомпилированный заголовок. Предположим, что ваш заголовок имеет
#ifndef FOO
void foo();
#endif
Теперь предположим, что вы прекомпилируете этот заголовок.
В другом исходном файле ничего не мешает вам определить FOO
перед включением заголовка. Если вы это сделаете, прекомпилированный заголовок не должен использоваться, но единственный способ, которым может знать компилятор, - это отслеживать каждый макрос, который используется в любом месте заголовка.
Это очень много работы. GCC делает это, но Microsoft решила не делать этого.
Гораздо проще сказать, что прекомпилированные заголовки разрешены только в нескольких конкретных сценариях, и если большие варианты использования покрываются этими несколькими конкретными сценариями, это достаточно хорошо.
Вы должны сообщить IDE, следует ли создавать PCH. –
Пожалуйста, не слепите в пояснительную записку о том, что должно быть улучшено. Спасибо –