В отношении препроцессора, похоже, много путаницы.
Что делает компилятор, когда видит #include
, что он заменяет эту строку содержимым включенных файлов, без вопросов.
Итак, если у вас есть файл a.h
с таким содержанием:
typedef int my_number;
и файл b.c
с таким содержанием:
#include "a.h"
#include "a.h"
файл b.c
будет переведен препроцессором перед компиляцией в
typedef int my_number;
typedef int my_number;
, что приведет к ошибке компилятора, поскольку тип my_number
определяется дважды. Несмотря на то, что определение одно и то же, это не допускается языком Си.
Поскольку заголовок часто используется более чем в одном месте, включают охрану , как правило, используются в C. Это выглядит так:
#ifndef _a_h_included_
#define _a_h_included_
typedef int my_number;
#endif
Файл b.c
по-прежнему будет содержать все содержимое заголовка дважды после предварительной обработки. Но второй экземпляр будет проигнорирован, поскольку макрос _a_h_included_
уже будет определен.
Это работает очень хорошо, но имеет два недостатка. Прежде всего, должны быть включены защитные элементы, а имя макроса должно быть разным в каждом заголовке. И, во-вторых, компилятор все еще должен искать заголовочный файл и читать его так часто, как он включен.
Objective-C имеет инструкцию препроцессора #import
(она также может использоваться для кода на C и C ++ с некоторыми компиляторами и опциями). Это делает почти то же самое, что и #include
, но также отмечает, какой файл уже был включен. Строка #import
заменяется содержимым именованного файла только при первом обнаружении. Каждый раз после этого это просто игнорируется.