Это процесс:
source header source header header
\ / \ | //
\ / \ | //
PREPROCESSOR PREPROCESSOR
| |
V V
preprocessed code preprocessed code
| |
COMPILER COMPILER
| |
V V
object code object code
\ /
\ /
\ /
LINKER
|
V
executable
Препроцессирование
#include
для этого первого шага. Он инструктирует препроцессор обрабатывать указанный файл и вставляет результат в выходной файл.
Если A
включает B
и C
и B
включает C
, выход препроцессор для A
будет включать обработанный текст C
дважды.
Это проблема, так как это приведет к дублированию деклараций. Исправление состоит в том, чтобы использовать препроцессорные переменные, отслеживать, включен ли исходный код (aka head guard).
#ifndef EXAMPLE_H
#define EXAMPLE_H
// header contents
#endif
В первый раз, EXAMPLE_H
не определен, и препроцессор будет оценивать содержимое в блоке с ifndef
/endif
. Во второй раз он пропустит этот блок. Таким образом обработанный вывод изменяет, и определения включены только один раз.
Это настолько часто, что есть нестандартная директива реализована некоторые компиляторы, которые короче и не требуют выбора уникального переменного препроцессора:
#pragma once
// header contents
Вы можете выяснить, как портативными вы хотите, чтобы ваш C/C++, и какой защитник заголовка использовать.
Защитные устройства для заголовков гарантируют, что содержимое каждого файла заголовка будет присутствовать не более одного раза в предварительно обработанном коде для единицы перевода.
Компиляция
компилятор генерирует машинный код с препроцессором C/C++.
Как правило, файлы заголовков включают объявления, а не фактические определения (аналогичные реализации). Компилятор содержит таблицу символов для всего, что в настоящее время отсутствует в определении.
Связывание
Компоновщик объединяет объектные файлы. Он соответствует определениям (аналогичным реализациям) со ссылками на таблицу символов.
Возможно, что два объектных файла предоставляют определение, а компоновщик - один.Это происходит, если вы поместили исполняемый код в свои заголовки. Это обычно не происходит в C, но это происходит очень часто в C++ из-за шаблонов.
Заголовок «код», будь то декларации или определения, включается несколько раз во все объектные файлы, но компоновщик объединяет все это вместе, так что он присутствует только один раз в исполняемом файле. (Я исключаю встроенные функции, которые присутствуют несколько раз.)
* «заголовочный файл (с включенными защитами) будет включаться только один раз в одну единицу перевода, но несколько раз во всем коде. ?"* Да. Не один раз в программу, он (не более) один раз на единицу перевода. – CoryKramer
С включением охранников заголовок может быть включен несколько раз даже в одном блоке перевода, но большая часть его (часть внутри охранников) будет пропущена через первый раз. Препроцессору все равно, где он был ранее включен ... только если был определен макрос охраны (что происходит в первый раз, когда он включен, если охранники настроены правильно). – Dmitri
Спасибо. Мне нравится этот сайт :) супер быстрые ответы и отличные ответы. – Engineer999