Dường như có rất nhiều nhầm lẫn liên quan đến bộ tiền xử lý.
Trình biên dịch sẽ làm gì khi thấy #includenó thay thế dòng đó bằng nội dung của các tệp được bao gồm, không có câu hỏi nào được hỏi.
Vì vậy, nếu bạn có một tập tin a.hvới nội dung này:
typedef int my_number;
và một tệp b.ccó nội dung này:
#include "a.h"
#include "a.h"
tập tin b.csẽ được dịch bởi bộ tiền xử lý trước khi biên dịch thành
typedef int my_number;
typedef int my_number;
Điều này sẽ dẫn đến một lỗi biên dịch, vì loại my_numberđược xác định hai lần. Mặc dù định nghĩa là giống nhau nhưng điều này không được phép bởi ngôn ngữ C.
Vì một tiêu đề thường được sử dụng ở nhiều nơi, bao gồm các vệ sĩ thường được sử dụng ở C. Điều này trông giống như sau:
#ifndef _a_h_included_
#define _a_h_included_
typedef int my_number;
#endif
Tệp b.cvẫn có toàn bộ nội dung của tiêu đề trong đó hai lần sau khi được xử lý trước. Nhưng trường hợp thứ hai sẽ bị bỏ qua vì macro _a_h_included_đã được xác định.
Điều này hoạt động thực sự tốt, nhưng có hai nhược điểm. Trước hết, các vệ sĩ bao gồm phải được viết và tên macro phải khác nhau trong mỗi tiêu đề. Và thứ hai, trình biên dịch vẫn phải tìm tệp tiêu đề và đọc nó thường xuyên như nó được bao gồm.
Objective-C có #importhướng dẫn tiền xử lý (nó cũng có thể được sử dụng cho mã C và C ++ với một số trình biên dịch và tùy chọn). Điều này gần giống như #include, nhưng nó cũng lưu ý bên trong tập tin nào đã được đưa vào. Các #importdòng được chỉ thay thế bằng nội dung của file có tên lần đầu tiên nó gặp phải. Mỗi lần sau đó nó chỉ bị bỏ qua.