2017-02-10 15 views
-3

Я понимаю, что цель прекомпилированного заголовка заключается в ускорении процесса компиляции с использованием объектного файла, который уже был скомпилирован один раз и связать его с фактическим проектом. Но я не понимаю, почему я должен явно применять Visual Studio для использования stdafx.h (Project Properities -> C/C++ -> Precompiled Headers -> Precompiled Header)? Почему не #include "stdafx.h" недостаточно?Почему не включает stdafx.h, недостаточно для VisualStudio?

+2

Вы должны сообщить IDE, следует ли создавать PCH. –

+0

Пожалуйста, не слепите в пояснительную записку о том, что должно быть улучшено. Спасибо –

ответ

2

Предполагается, что так называемый stdafx.h выглядит как обычный заголовочный файл. В его имени нет ничего особенного. Он не должен автоматически включать предварительно скомпилированные заголовки.

Идея состоит в том, что stdafx.h будет рассматриваться как обычный заголовочный файл любым другим компилятором и/или когда у вас нет того, что использовать заголовки прекомпиляторов в MSVC.

Это вы, кто должен сказать, компилятор MSVC, что вы на самом деле хотите , чтобы включить скомпилированные заголовки. Именно поэтому у вас есть эта настройка проекта. И только когда вы включаете предварительно скомпилированные заголовки, stdafx.h получит свою особую роль и получит специальное обращение от компилятора. И это не обязательно stdafx.h. Вы можете назначить эту специальную роль любому другому заголовку, указав другое имя в настройках проекта.

Фактически, просмотр ссылки на AFX в проекте, который не имеет ничего общего с библиотеками или фреймами, специфичными для Microsoft, будет довольно странным.

+0

Не могли бы вы уточнить, какая именно специальная обработка получает «stdafx.h» из компилятора? Как это отличается от классического процесса компоновки компиляции? –

+1

@ Вакан Танка: Предварительная компиляция заголовка не имеет ничего общего с «связыванием». Это совершенно другой процесс. «Специальное обращение», которое получает «stdafx.h», в основном таково: его содержимое * предварительно скомпилировано * только один раз, а затем используется в прекомпилированной форме. Вот и все. – AnT

+0

«Это вы должны сообщить компилятору MSVC, что вы действительно хотите включить прекомпилированные заголовки». Разве я не сказал это в MSVC, когда я делал «#include» stdafx.h »? –

3

Почему нет #include "stdafx.h" [...] достаточно?

Потому что это стандартная директива препроцессора C++. * Он ничем не отличается от #include <string> в отношении компилятора. Если вам нужна дополнительная семантика, вы должны сообщить об этом компилятору.

Поскольку, похоже, существует путаница, как Visual Studio реализует прекомпилированные заголовки, вот ссылка на документацию: Creating Precompiled Header Files.


*Имейте в виде, что нет ничего особенного имени "stdafx.h", кроме того, что имя заголовка по умолчанию используется для создания РСНЫ.

+0

Согласовано в моих проектах Visual Studio, заголовок PCH даже не называется 'stdafx.h'. Хотя я использую макрос с CMake, который указывает имя заголовка PCH .. – drescherjm

+0

Извините, но я не следую. Какая дополнительная семантика? Компилятор просто заменяет '#include" stdafx.h "' содержимым 'stdafx.h'. С этого момента я могу вызывать функции, объявленные в 'stdafx.h', и компилятор не будет жаловаться. После компиляции файл stdafx.obj связан с моим проектом. Я не вижу необходимости явно указывать что-то еще здесь. –

+0

@WakanTanka: Вы описали ** стандартную ** семантику. Дополнительная семантика заключается в том, что компилятор заменяет директиву '# include' на ** предварительно обработанную ** и ** предварительно скомпилированную ** версию заголовка. Кроме того, файлы заголовков не являются единицами компиляции. Нет файла * stdafx.obj * * (если вы также не указали * * stdafx.cpp * * файл, который вы делаете для PCH). Файл .obj не имеет ничего общего с PCH. – IInspectable

-1

Несложно ли ответить на вопрос, можно ли безопасно использовать предварительно скомпилированный заголовок. Предположим, что ваш заголовок имеет

#ifndef FOO 
void foo(); 
#endif 

Теперь предположим, что вы прекомпилируете этот заголовок.

В другом исходном файле ничего не мешает вам определить FOO перед включением заголовка. Если вы это сделаете, прекомпилированный заголовок не должен использоваться, но единственный способ, которым может знать компилятор, - это отслеживать каждый макрос, который используется в любом месте заголовка.

Это очень много работы. GCC делает это, но Microsoft решила не делать этого.

Гораздо проще сказать, что прекомпилированные заголовки разрешены только в нескольких конкретных сценариях, и если большие варианты использования покрываются этими несколькими конкретными сценариями, это достаточно хорошо.