Как единица компиляции определена в С++?

Возможный дубликат:
Что такое "единица перевода" на С++

Часто говорят, что статические переменные, объявленные в C/С++, не отображаются во всех единицах компиляции? Означает ли это, что каждый .c или .cpp файл является отдельным модулем компиляции? Как насчет файла a, h и статических переменных, объявленных в файле .h? Файл .h также рассматривается как отдельный блок компиляции?

Ответ 1

Заголовочные файлы не имеют отдельной жизни, только их содержимое #included в .c или .cpp файлы. Но поскольку #include обрабатывается препроцессором, компилятор не знает о различных файлах заголовков; он видит только полученный код в качестве ввода. Это то, что называется единицей компиляции: исходный файл со всеми его директивами #include заменен содержимым соответствующих файлов заголовков.

Ответ 2

Компиляция C и С++ (обычно) делится на три независимых этапа:

  • Предварительная обработка с использованием макросов и расширений #include.
  • Компиляция, преобразование исходного кода в двоичный код и создание объектных файлов-посредников.
  • Связывание, объединение объектных файлов в один файл ELF или EXE.

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

Фактический компилятор (обычно) не знает ни одного файла заголовка, он видит компилятор как большой файл .c или .cpp.

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

Ответ 3

Компилятор обрабатывает только исходные файлы, обычно с расширением .c или .cpp. Компилятор действительно не заботится о файлах, которые включены: поскольку компилятор обычно реализуется, каждый файл .c/.cpp обрабатывается заново, любые файлы .h читаются (любезно предоставлено препроцессором).

Вот почему мы говорим о "единицах компиляции": что-то, скомпилированное за один раз, результаты которого впоследствии могут быть связаны вместе с исполняемыми файлами.