Кажется, есть много путаницы в отношении препроцессора.
Что делает компилятор, когда он видит, #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
Линия заменяется только содержимое указанного файла в первый раз она встречается. Каждый раз после этого это просто игнорируется.