首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C/C++條件編譯全攻略:#ifdef、#ifndef、#define、#endif 實戰解析

     編輯:關於C語言

為什麼需要條件編譯?

跨平台、多配置構建時,源碼需根據宏定義選擇性編譯不同代碼路徑,避免維護多份副本。標準庫(如 STL)大量使用此技術適配編譯器/平台差異。

核心指令詳解

1. 防止頭文件重複包含:#ifndef / #define / #endif


// json_autolink.h
#ifndef JSON_AUTOLINK_H_INCLUDED
#define JSON_AUTOLINK_H_INCLUDED

// ... 類/函數聲明 ...

#endif // JSON_AUTOLINK_H_INCLUDED
  • 首次包含:宏未定義 → 定義宏 → 編譯內容。
  • 再次包含:宏已定義 → 跳過內容 → 避免重複定義錯誤。
  • 現代替代:#pragma once(編譯器擴展,非標準但廣泛支持)。

2. 功能開關:#ifdef / #else / #endif


#ifdef JSON_VALUE_USE_INTERNAL_MAP
class ValueAllocator;
class ValueMapAllocator;
// ... 內部實現細節 ...
#endif
  • 構建系統 (CMake/Make) 中通過 -DJSON_VALUE_USE_INTERNAL_MAP 或配置頭文件 #define JSON_VALUE_USE_INTERNAL_MAP 控制是否編譯該模塊。
  • 實現“同一代碼庫,不同配置產物”。

3. 複雜條件判斷:#if / #elif / #else / #endif 配合 defined()


#if defined(_PTHREADS) && !defined(_NOTHREADS)
#define __STL_PTHREADS
#endif

#if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS)
#define __STL_UITHREADS
#endif

#if defined(__sgi) && !defined(__GNUC__)
#include 
#if !defined(_BOOL)
#define __STL_NO_BOOL
#endif
#if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32
#define __STL_STATIC_CONST_INIT_BUG
#endif
#endif
  • defined(MACRO) 返回 1/0,可用於 #if 表達式中,比 #ifdef 更靈活(支持邏輯運算)。
  • 可檢測預定義宏(__GNUC__, _WIN32, __linux__ 等)實現平台適配。
  • 可比較宏數值(_COMPILER_VERSION >= 730)。

4. 宏定義 #define 的雙重角色

  • 常量/宏函數:#define MAX 100, #define SQR(x) ((x)*(x))。建議改用 const/constexpr 和 inline 函數,擁有類型安全、作用域、調試可見性。
  • 條件編譯標記:僅作為 #ifdef/#if defined() 的判斷依據,不產生代碼。

最佳實踐建議

  1. 宏名使用項目前綴 + 大寫(如 MYLIB_USE_SSL),避免衝突。
  2. 配置宏集中放在 config.h,由構建系統生成或手動維護。
  3. 避免過深的嵌套 #if,增加閱讀難度;必要時拆分為獨立源文件。
  4. 善用編譯器預定義宏檢測環境,而非手動定義平台宏。
條件編譯是 C/C++ 靜態多態的基石,善用之可構建高可移植、可配置的代碼庫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved