Здається, існує велика плутанина щодо препроцесора.
Що робить компілятор, коли бачить, #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 не дозволена.
Оскільки заголовок часто використовується в більш ніж одному місці, в ньому також використовуються щитки, які зазвичай використовуються в 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
Лінія замінюється тільки вміст зазначеного файлу в перший раз вона зустрічається. Кожен раз після цього його просто ігнорують.