Header guards C++ là gì

Khi làm quen với C hoặc C++ chắc bạn sẽ rất quen với mấy dòng kiểu như sau ở đầu và cuối mỗi file .h #ifndef  _file_name_h #define _file_name_h /* file content */ #endif

Những dòng trên được gọi là Include Guard (thực ra chính xác hơn là #include guard) đến đây thì bạn cũng lờ mờ đoán ra mớ code nhiều dấu thăng ở trên để làm cái gì rồi. Đại khái là nó sẽ để bảo vệ cho đồng chí #include mà các bạn sẽ dùng để import file khác vào. Vậy tại sao lại phải bảo vệ. Đê biết được tác dụng của nó chúng ta sẽ xét đến ví dụ  không có Include Guard sau.

File "AV.h" struct star { int age; };

File "AsianAV.h" #include "AV.h"

File "JAV.h" #include "AV.h" #include "AsianAV.h"

Ở đây bạn sẽ gặp lỗi khi cố biên dịch file JAV.h vì nó đã vô tình include 2 lần file "AV.h" và cùng với đó thì kiểu struct start cũng sẽ được define 2 lần. Điều này rõ ràng là sẽ gây ra lỗi. Đến đây thì chúng ta sẽ thêm Include Guard vào file AV.h để sửa lỗi này

New "AV.h" #ifndef  _av_h_ #define _av_h_ struct star { int age; }; #endif

Lần này thì lỗi sẽ không hỏi thăm chúng ta nữa. Nhưng hãy làm rõ mấy câu lệnh đơn giản trên 1 chút. Đầu tiên câu lệnh #ifndef _av_h_ sẽ kiểm tra xem đã có cái nào tên là _av_h_ được định nghĩa chưa.

  • Nếu chưa thì sẽ chạy tiếp các câu lệnh ở dưới là #define _av_h_ sẽ định nghĩa cái tên _av_h_. Sau đó thì mọi thứ diễn ra bình thường.
  • Nếu đã được định nghĩa (việc này xảy ra khi bạn include file av.h lần thứ 2) thì trình biên dịch sẽ nhảy luôn xuống lệnh #endif và lúc này lệnh #include sẽ không khác gì hơn ngoài include 1 file trống.

Đó là cơ chế mà Include Guard hoạt động. Nếu bạn thấy hay và  hữu ích, đừng quên like và tín dụng cùng comment cho tác giả để tác giả có thêm ham muốn để viết tiếp nhiều bài nữa.

Update: Các bạn có thể dùng #pragma để thay thế cho include guard bằng cách viết #pragma once // header file code

directive này hầu hết được hỗ trợ bởi các compiler lớn bao gồm  Clang, GCC, the Intel C++ compiler và MSVC.