Chuyển tới nội dung chính

Các chỉ thị tiền xử lý trong C/C++

Chỉ thị tiền xử lý (preprocessor directives) trong C/C++ là những lệnh bắt đầu bằng dấu # và được xử lý trước khi trình biên dịch thực sự biên dịch mã nguồn. Chúng không tạo ra mã máy, mà điều khiển cách mã nguồn được biên dịch, bao gồm việc nhúng file, định nghĩa macro, hoặc kiểm soát điều kiện biên dịch.

Nhóm chèn và điều khiển mã nguồn

#include
Dùng để chèn nội dung của một file khác vào file hiện tại.

#include <iostream>      // thư viện chuẩn
#include "mylib.hpp" // file do người dùng định nghĩa

#define#undef
Dùng để định nghĩa hoặc hủy định nghĩa một macro.

#define PI 3.14
#define DEBUG
#undef DEBUG

Nhóm điều kiện biên dịch (Conditional Compilation)

#if, #ifdef, #ifndef, #elif, #else, #endif
Cho phép biên dịch có điều kiện

#define DEBUG

#ifdef DEBUG
std::cout << "Debug mode" << std::endl;
#else
std::cout << "Release mode" << std::endl;
#endif

Nhóm điều khiển biên dịch hoặc hệ thống

#pragma
Chỉ thị đặc biệt gửi đến trình biên dịch, mỗi trình biên dịch sẽ có các #pragma riêng.

Bỏ qua cảnh báo (với clang)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
for (size_t i = 0; i < n; i++) { arr[i] = static_cast<int>(i); }
for (size_t i = 0; i < n; i++) { std::cout << arr[i] << " "; }
#pragma clang diagnostic pop
Chỉ định nạp header 1 lần duy nhất
#pragma once
Điều khiển căn lề struct (packing)
#pragma pack(push, 1)
struct Packet {
char a;
int b;
};
#pragma pack(pop)

#error#warning
Sinh lỗi hoặc cảnh báo trong quá trình biên dịch.

#ifndef VERSION
#error "Macro VERSION chưa được khai báo!"
#endif

#line
Dùng để thay đổi số dòng được báo lỗi trong compiler.

#line 100 "myfile.cpp"

lưu ý
  • Dùng #pragma once thay include guard (#ifndef) để ngắn gọn.
  • Tránh macro phức tạp; ưu tiên inline hoặc constexpr trong C++.
  • Kiểm tra tính tương thích của #pragma với trình biên dịch (ví dụ: #pragma pack được hỗ trợ, nhưng một số chỉ thị khác có thể không).