Visual studio заставляет включать предварительно скомпилированный заголовочный файл во все единицы компиляции проекта?

Когда компилятор компилирует исходный файл (например, *.cpp), он создает объектный файл (например, *.o), чтобы позже он был связан с другими файлами .o и .so (.lib файлы для Windows) и составлял исполняемый файл.

Теперь для аналогичной ситуации, когда файлы заголовков не компилируются каждый раз, когда создается несколько файлов .pch, чтобы он затем связать его компоновщиком.

Теперь, если в рамках проекта Visula Studio определен предварительно скомпилированный заголовок, то почему Visual Studio жалуется с ошибкой (например, **fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?**), что файл заголовка не включен в файл .cpp.

Подводя итог, вот мои вопросы:

  1. Зачем в каждом .cpp файле нужен предварительно скомпилированный заголовок проекта?
  2. Как требование наличия предварительно скомпилированного заголовка в каждой единице компиляции оптимизирует процесс компиляции? Другими словами, в чем польза этого требования? (Пользователь может решить, где включить, а где нет!)
  3. Если предварительно скомпилированный заголовок включен в файл .cpp, который использует только 2% того, что находится в файле .pch, то оставшиеся 98% будут добавлены в соответствующий файл .o в?

person Narek    schedule 19.09.2012    source источник
comment
Для предварительно скомпилированных заголовков нет стандартной модели компиляции. Каждый компилятор определяет свои собственные правила и семантику.   -  person Kerrek SB    schedule 19.09.2012


Ответы (3)


Зачем в каждом .cpp файле нужен предварительно скомпилированный заголовок проекта?

Потому что ты просил об этом. Если вы не хотите его использовать, вам нужно изменить параметр для файла .cpp. Щелкните его правой кнопкой мыши, "Свойства", "C / C ++", "Предварительно скомпилированные заголовки", "Создать / использовать" = "Не использовать предварительно скомпилированные заголовки". Настройка по умолчанию - «Использовать». В этом нет особого смысла.

Как предварительно скомпилированный заголовок в каждой единице компиляции оптимизирует процесс компиляции?

Отсутствие необходимости разбирать #includes. Особенно полезно, когда вы #include <windows.h>. Экономия времени измеряется секундами, в больших проектах с сотнями файлов .cpp, что в сумме составляет несколько минут. Это, безусловно, самый дешевый способ ускорить компилятор без потери качества сгенерированного кода.

тогда остальные 98% будут добавлены в соответствующий файл .o в?

Конечно, нет.

person Hans Passant    schedule 19.09.2012

  1. На самом деле нет необходимости включать предварительно скомпилированный заголовок в каждую единицу компиляции. Вы можете установить параметр «не использовать предварительно скомпилированный заголовок» для отдельного файла в разделе свойств C / C ++ -> Precompiled Headers для этого файла. Однако это большая работа, и я никогда не встречал никого, кто делал бы это в производственном коде.
  2. Оптимизация заключается в том, что предварительно скомпилированный заголовок создается только один раз, а весь shebang повторно используется для всех единиц компиляции без перекомпиляции / повторного включения (вроде). Если у вас есть набор файлов, которые включаются много раз, это может значительно сэкономить время компиляции. См. Также Уход за предварительно скомпилированными заголовками и их загрузка.
  3. Нет, вы не получите лишнего содержимого файла, как и при статической компоновке.
person Joris Timmermans    schedule 19.09.2012
comment
Однако это большая работа, и я никогда не встречал никого, кто делал бы это в производственном коде. - У нас это в производственном коде, так как наша статическая библиотека используется совместно с нашими продуктами для Linux. В Visual Studio вы можете выбрать несколько файлов CPP и настроить свойства таким образом. - person Class Skeleton; 14.08.2015

  1. Я предполагаю, что ваш вопрос означает «почему компилятор не может предположить, что этот заголовок всегда присутствует, если он является обязательным». Причина в том, что VS не хочет так сильно отклоняться от стандарта. Если ваш файл .cpp использует что-то из файла заголовка, он должен это включать. Таким образом, ваш файл будет скомпилирован точно так же, даже если вы отключите предварительно скомпилированные заголовки (только это займет больше времени).
  2. Как уже говорили другие, вы можете явно отключить предварительно скомпилированные заголовки для отдельных файлов, если хотите. Идея состоит в том, что вы должны включать в предварительно скомпилированный заголовок только те элементы, которые вы используете в большинстве, если не во всех своих файлах.
  3. Нет, результирующий объектный код должен быть одинаковым, независимо от того, был ли заголовок предварительно скомпилирован или нет.
person Gorpik    schedule 19.09.2012