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 #include
nó 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.h
với nội dung này:
typedef int my_number;
và một tệp b.c
có nội dung này:
#include "a.h"
#include "a.h"
tập tin b.c
sẽ đượ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.c
vẫ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ó #import
hướ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 #import
dò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.