Для чего используется «stdafx.h» в Visual Studio?

500

Файл с именем stdafx.h генерируется автоматически, когда я запускаю проект в Visual Studio 2010. Мне нужно создать кроссплатформенную библиотеку C ++, поэтому я не могу / не могу использовать этот заголовочный файл.

Для чего stdafx.hиспользуется? Это нормально, что я просто удалил этот заголовочный файл?

prosseek
источник
2
Если я получаю ошибку компиляции, связанную с stdafx.h, я обычно устанавливаю настройки, чтобы не создавать или использовать этот файл ..
phoad
6
Статья: StdAfx.h для новичков - viva64.com/ru/b/0265
Вы можете прекрасно использовать заголовочный файл на других платформах, для них это просто обычный заголовочный файл. Это просто не дает никакого выигрыша в производительности.
Андреа

Ответы:

826

Все компиляторы C ++ имеют одну серьезную проблему с производительностью. Компиляция кода C ++ - это долгий, медленный процесс.

Компиляция заголовков, включенных поверх файлов C ++, является очень длинным, медленным процессом. Компиляция огромных структур заголовков, которые являются частью Windows API и других больших библиотек API, является очень , очень долгим, медленным процессом. Необходимость делать это снова и снова и снова для каждого исходного файла Cpp - это смертельный звон.

Это не уникально для Windows, но это старая проблема, с которой сталкиваются все компиляторы, которые должны компилироваться с большим API, таким как Windows.

Компилятор Microsoft может решить эту проблему с помощью простого трюка, называемого предварительно скомпилированными заголовками . Хитрость довольно проста: хотя каждый CPP-файл может потенциально и юридически придать немного иной смысл цепочке заголовочных файлов, включенных в начало каждого Cpp-файла (такими вещами, как наличие разных макросов # define'd перед включениями, или включив заголовки в другом порядке), это чаще всего не так. В большинстве случаев у нас есть десятки или сотни включенных файлов, но все они имеют одинаковое значение для всех файлов Cpp, компилируемых в вашем приложении.

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

Хитрость заключается в назначении специального заголовочного файла в качестве отправной точки всех цепочек компиляции, так называемого файла «предварительно скомпилированного заголовка», который обычно является файлом с именем stdafx.h просто по историческим причинам.

Просто перечислите все ваши большие огромные заголовки для ваших API в файле stdafx.h, в соответствующем порядке, а затем начните каждый из ваших файлов CPP с самого верха #include "stdafx.h", перед любым значимым контентом (практически единственное, что разрешено ранее, это Комментарии).

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

Я не верю, что этот трюк уникален для компиляторов Microsoft, и при этом я не думаю, что это была оригинальная разработка.

Для компиляторов Microsoft, параметр , который контролирует использование прекомпилированы заголовки управляются с помощью аргумента командной строки для компилятора: /Yu "stdafx.h". Как вы можете себе представить, использование имени stdafx.hфайла - это просто соглашение; Вы можете изменить имя, если хотите.

В Visual Studio 2010 этот параметр управляется из графического интерфейса пользователя посредством щелчка правой кнопкой мыши по проекту CPP, выбора «Свойства» и перехода к «Свойства конфигурации \ C / C ++ \ Precompiled Headers». Для других версий Visual Studio расположение в графическом интерфейсе будет другим.

Обратите внимание: если вы отключите предварительно скомпилированные заголовки (или запустите свой проект с помощью инструмента, который их не поддерживает), это не сделает вашу программу незаконной; это просто означает, что ваш инструмент будет компилировать все с нуля каждый раз.

Если вы создаете библиотеку без зависимостей Windows, вы можете легко закомментировать или удалить файлы #includeиз stdafx.hфайла. Нет необходимости удалять файл как таковой, но, очевидно, вы также можете сделать это, отключив параметр заголовка прекомпиляции выше.

Евро Мицелли
источник
6
Даже если вы использовали только файлы из пространства имен std, вы получаете преимущество в скорости
Ghita
11
О боже, очень хороший ответ. Я искал стандартный совместимый c-компилятор. получается, что я могу отключить расширения micro $ oft в свойствах проекта, изменить компилятор с «auto» на «c», и у вас в значительной степени есть «стандартный» компилятор и IDE.
EKanadily
4
@Rishi: под «линией» ты имеешь в виду #include "stdafx.h"? Конечно, но это просто стандартный #include. Часть «MS extension» - это просто оптимизация производительности компилятора; это не меняет семантику наличия заголовочного файла, который называется «stdafx.h». Обратите внимание, что если вы удалите include и ваш код будет зависеть от всего, что было включено через stdafx.h, вам придется включить его напрямую.
Евро Мицелли
4
@ Youda008, не совсем так. Перед компиляцией файла кода содержимое заголовков просто и буквально «вставляется» в то место, где #includeони находятся в исходном файле (выполняется тем же этапом препроцессора, который оценивает макросы). Полученный итоговый файл затем передается фактическому компилятору, который никогда не видит заголовочный файл как отдельную сущность. Вы только помещаете объявления в заголовочный файл, потому что это то, что хорошо работает с заголовочным файлом - это обычное правило. Попробуй это! Создайте заголовочный файл со всей программой, а затем создайте исходный файл, в котором есть только #include. Компилируется нормально.
Евро Мицелли
28
Историческое любопытство. Название stdafx.h датируется примерно 1992 годом, когда MFC назывался «Application Framework Extensions» перед его выпуском. Visual Studio 2015 по-прежнему имеет имя по умолчанию ..
Kert
48

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

Если вы создаете кроссплатформенное приложение, отметьте «Пустой проект» при создании проекта, и Visual Studio вообще не будет помещать файлы в ваш проект.

Касабланка
источник
15
В этом файле нет ничего, что не работало бы на других платформах. Это может замедлить компиляцию, если компилятор не поддерживает предварительно скомпилированные заголовки, но не должен нарушать его. Это просто заголовочный файл, который включает другие заголовочные файлы.
расстроен
2
@detunized: Возможно, мой ответ заставил это звучать иначе, так что спасибо за разъяснение этой части.
Касабланка
3

«Stdafx.h» - это предварительно скомпилированный заголовок. Он включает в себя файл для стандартных системных включаемых файлов и для конкретных включаемых файлов, которые используются часто, но изменяются нечасто. Это сокращает время компиляции и ненужную обработку.

Предварительно скомпилированный заголовок stdafx.h в основном используется в Microsoft Visual Studio, чтобы дать компилятору информацию о файлах, которые когда-то были скомпилированы, и не нужно его компилировать с нуля. Вы можете прочитать больше об этом

http://www.cplusplus.com/articles/1TUq5Di1/

https://docs.microsoft.com/en-us/cpp/ide/precompiled-header-files?view=vs-2017

Акаш дас
источник
-10

Я сам столкнулся с этим, так как я пытаюсь создать самодостаточный фреймворк, но начал с создания новой опции Win32 Program в Visual Studio 2017. "stdafx.h" не нужен и должен быть удален. Затем вы можете удалить тупые «stdafx.h» и «stdafx.cpp», которые есть в вашем обозревателе решений, а также файлы из вашего проекта. На это место нужно поставить

#include <Windows.h>

вместо.

Адам Х.
источник