24. Luôn viết #include bảo vệ bên trong. Không bao giờ viết #include bảo vệ bên ngoài.

Estimated reading: 3 minutes 239 views

Tóm tắt

Hãy bảo vệ cho Header: Ngăn chặn việc include nhiều lần không mong muốn bằng cách sử dụng bảo vệ include guard với tên duy nhất cho tất cả các tập tin header của bạn.

Thảo luận

Mỗi tập tin header nên được bảo vệ bởi một include guard nội bộ để tránh lỗi định nghĩa lại (redefinition) trong trường hợp nó được #include nhiều lần.
Ví dụ, một tập tin header có tên là foo.h nên tuân theo dạng tổng quát như sau:

				
					#ifndef FOO_H_INCLUDED_
#define FOO_H_INCLUDED_

// ... nội dung của tập tin ...

#endif				
			

Khi định nghĩa include guard, hãy tuân thủ các quy tắc sau:

  • Sử dụng tên bảo vệ (guard) duy nhất: Đảm bảo tên bảo vệ là duy nhất, ít nhất trong phạm vi ứng dụng của bạn. Ví dụ trên sử dụng một quy ước phổ biến; tên bảo vệ có thể bao gồm cả tên ứng dụng, và một số công cụ còn tạo tên bảo vệ chứa cả số ngẫu nhiên.

  • Đừng cố tỏ ra thông minh: Không nên viết bất kỳ đoạn mã hoặc chú thích nào trước hoặc sau phần đã được bảo vệ, và hãy tuân theo đúng mẫu chuẩn như đã minh họa ở trên. Các trình tiền xử lý (preprocessor) hiện đại có thể nhận diện include guard, nhưng chúng có thể bị giới hạn về “trí thông minh” và thường kỳ vọng đoạn mã guard xuất hiện chính xác ở phần đầu và cuối của tập tin header.

Tránh sử dụng các include guard bên ngoài đã lỗi thời như những gì được khuyên trong các tài liệu cũ:

				
					#ifndef FOO_H_INCLUDED_ // KHÔNG khuyến nghị
#include "foo.h"
#define FOO_H_INCLUDED_
#endif				
			

Các include guard bên ngoài như trên thường rườm rà; lỗi thời với các trình biên dịch ngày nay;  “dễ vỡ” khi gây ra phụ thuộc chặt, vì cả bên gọi (callers) lẫn file header phải cùng đồng ý về tên của bảo vệ (guard).

Ngoại lệ

Trong những trường hợp rất hiếm, một tập tin header có thể được thiết kế để được #include nhiều lần một cách có chủ ý. → Ví dụ kinh điển

Tham khảo

[C++03, §2.1] • [StroustrupOO] §9.3.3

Link

Leave a Comment

Chia sẻ:

24. Luôn viết #include bảo vệ bên trong. Không bao giờ viết #include bảo vệ bên ngoài.

Or copy link

CONTENTS