Bộ tiền xử lý trong c tiếng anh là gì
Preprocessor ( bộ tiền giải quyết và xử lý ) là một khái niệm đặc trưng trong C / C + +, đó là một công cụ được thực thi trước khi quy trình biên dịch thực sự được thực thi . Show Bộ tiền xử lý có nhiệm vụ xử lý các chỉ thị tiền xử lý, như #include, #define, #if, #ifdef, #ifndef, #endif,… Nó làm việc trên một file source C++ tại một thời điểm bằng cách thay thế các chỉ thị #include bằng nội dung của các file tương ứng (thường chỉ chứa khai báo), thay thế các macro #define và chọn các phần khác nhau trong source code để biên dịch tùy thuộc vào các chỉ thị #if, #ifdef, #ifndef. Trong bài này mình sẽ tổng hợp 1 số best practice về Preprocessor Include GuardsTrong bài này mình sẽ tổng hợp 1 số best practice về Preprocessor Một file source có thể include một hoặc nhiều file header. Và một file header có thể include một hoặc nhiều file header khác. Do đó một source file include nhiều file header thì có thể gián tiếp include một file header nào đó nhiều lần. Nếu một file header được include nhiều lần mà trong file đó có chứa định nghĩa struct, class, … thì khi biên dịch sẽ bị lỗi. “include guards” thường được dùng để tránh lỗi này. Để áp dụng “include guards” thì chúng ta sẽ sử dụng các chỉ thị #define, #ifndef, #endif. Ví dụ →
“ include guards ” hoàn toàn có thể work ok với toàn bộ những standard compiler và preprocessor. Vấn đề mà những dev cần chú ý quan tâm ở đây là làm thế nào bảo vệ tính duy nhất của macro dùng để guard. Ví dụ trong trường hợp này, nếu có nhiều hơn 1 header file cùng sử dụng FOO_H làm macro để guard thì hoàn toàn có thể dẫn đến lỗi do include thiếu header. Và nếu trong project của tất cả chúng ta có sử dụng thư viện của bên thứ 3 nữa thì năng lực bị trùng sẽ càng cao . Để tránh rắc rối khi sử dụng “include guards” bằng macro thì hầu hết các trình biên dịch C++ hiện nay đều support chỉ thị #pragma_once để đảm bảo một header chỉ được include một lần vào 1 file source. Ví dụ →
Tuy nhiên ae phải nhớ rằng cái này ko thuộc ISO C + + standard nên không bảo vệ toàn bộ những trình biên dịch đều tương hỗ nhé, và những compiler ko tương hỗ sẽ bí mật lặng lẽ bỏ lỡ thông tư này . Conditional pre-processing logic“ Conditional pre-processing logic ” – “ tiền giải quyết và xử lý điều kiện kèm
theo logic ” là việc làm cho những phần code nào đó trở nên available hoặc unavailable trong quy trình biên dịch bằng cách sử dụng những thông tư tiền giải quyết và xử lý điều kiện kèm theo .
* Ví dụ 1: Sử dụng Conditional pre-processing trong cross-plaform source code (source code hỗ trợ nhiều platform)
Các macro như _WIN32, _WIN64 hay __unix__ được compiler tự động define dựa vào cấu hình build * Ví dụ 2: Mở code in log riêng với chế độ build Testing
* Ví dụ 3: Implement 1 tính năng mà chỉ có ở bản Premium
Lưu ý: MacroMacro là hoàn toàn có thể coi một kỹ thuật dùng để copy paste code tự động hóa tại thời gian biên dịch, ở đó những đoạn code được lặp lại ở nhiều chỗ sẽ được đóng thành macro và sẽ được preprocessor đưa vào nơi thiết yếu trước khi biên dịch. macro hoàn
toàn có thể chia thành 2 loại chính : object-like và function-like .
Ví dụ → Macro thường được viết hoa hàng loạt để dễ nhận ra khi đọc code. * Khi preprocessor gặp một object-like macro thì hành vi của nó đơn thuần chỉ là copy-paste, macro name sẽ được sửa chữa thay thế bởi định nghĩa của nó. Còn khi gặp một function-like macro, macro name sẽ được thay thế sửa chữa bởi định nghĩa của nó đồng thời những tham số cũng được thay bởi tên tham số thật. Ví dụ →* Các ae code C / C + + luôn luôn có thói quen kết thúc 1 dòng lệnh bằng dấu ; và nhiều lúc điều đó lại gây lỗi rất vớ vẩn khi dùng macro. Ví dụ →
__VA_ARGS__ trong phần định nghĩa macro. Ví dụ →
Predefined macrosTrong ví dụ này việc có 2 dấu ; ở cuối line 3 sẽ làm cho compiler không nhận ra else ở line số 4 là cùng block với lệnh if ở line số 2 dẫn đến compiler lỗiDo đó ae cần rất là chú ý khi dùng dấu ; trong định nghĩa macro * Trong trường hợp định nghĩa macro quá dài thì hoặc muốn tách ra nhiều line cho dễ nhìn thì hoàn toàn có thể sử dụng ký tự backslash ở cuối dòng để nối xuống dòng tiếp theo → * Variadic macros : Macro này đặc biệt
quan trọng ở chỗ hoàn toàn có thể lấy một số lượng tham số ( không xác lập trước ) thay vàotrong phần định nghĩa macro. Ví dụ → sau khi preprocessor giải quyết và xử lý thì compiler sẽ thấy như thế nàyPredefined macros là những macro được define bởi trình biên dịch. Ae chớ có nghịch ngu mà define lại ( re-define ) hoặc undefine những predefined macro nhé .
Ngoài ra còn 1 số predefined macro khác nữa nhưng ko thông dụng và ít gặp trong code
ứng dụng thường thì nên mình ko đề cập vào đây .
Preprocessor Operators (Toán tử tiền xử lý)Một số ví dụ sử dụng predefined macro → * Toán tử # hay còn gọi là “stringizing operator” được sử dụng để chuyển 1 tham số của macro thành string. chỉ có thể sử dụng với macro có tham số. Ví dụ →
## hay còn gọi là “Token pasting operator” được sử dụng để nối 2 tham số của macro. Ví dụ →
Preprocessor error messages↓ sẽ được preprocessor convert thành * Toán tửhay còn gọi là “ Token pasting operator ” được sử dụng để nối 2 tham số của macro. Ví dụ → ↓ sẽ được preprocessor convert thànhoutput sẽ làLỗi compile hoàn toàn có thể được định nghĩa sử dụng preprocessor. Nó khá hữu dụng trong trường hợp cần thông tin lỗi compile tương quan đến platform hoặc compiler version .
* Ví dụ : khi compile source code có đoạn code sau thì sẽ gặp lỗi báo lỗi compile “ Apple products are not supported in this release ” nếu compile code để chạy trên Apple device— Phạm Minh Tuấn ( Shun ) — |