#define RTA_ALIGNTO 4
#define RTA_ALIGN(len) (((len) + RTA_ALIGNTO - 1) & ~(RTA_ALIGNTO - 1))
RTA_ALIGNTO:對齊基數(這裡 4 位元組)。RTA_ALIGN(len):將 len 向上調整為 RTA_ALIGNTO 的倍數。常用於 Netlink 訊息、結構體序列化、DMA 緩衝區對齊。#ifdef DEBUG
#define DPRINT(fmt, ...) do { printf(fmt, ##__VA_ARGS__); } while (0)
#else
#define DPRINT(fmt, ...) /* 釋出版本完全展開為空,零開銷 */
#endif
do { ... } while (0):確保巨集在語句位置表現如單一語句,支援後接分號,避免 if (...) DPRINT(...); else ... 語法錯誤。##__VA_ARGS__:GNU 擴展,當可變參數為空時自動移除前導逗號,支援 DPRINT("hello") 與 DPRINT("%d", x) 兩種寫法。NDEBUG 或未定義 DEBUG) 時巨集消失,無函數呼叫開銷。#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, TYPE, MEMBER) \
((TYPE *)((char *)(ptr) - offsetof(TYPE, MEMBER)))
offsetof:標準庫已提供 (<stddef.h>),此處展示原理。container_of:Linux 核心風格,從成員指標反推包含結構體指標。廣泛用於鏈表節點、裝置驅動私有資料結構。#define STATIC_ASSERT(cond, msg) \
typedef char static_assert_##msg[(cond) ? 1 : -1]
條件為假時產生負數陣列大小編譯錯誤,訊息包含 msg。C11 後請改用標準 _Static_assert(cond, msg)。
#define MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})
typeof 與語句表達式,確保參數僅評估一次,支援整數、浮點、指標等可比較型別。static inline int max(int a, int b) { return a>b?a:b; }。#define STR(x) #x
#define XSTR(x) STR(x) // 雙層展開宏參數
#define CAT(a, b) a##b
#define XCAT(a, b) CAT(a, b) // 雙層展開
#:參數字串化。##:記號連接。XSTR, XCAT) 確保參數若為宏會先展開再處理。#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
**僅適用於靜態陣列**,指標傳入會失效。C++17 可用 std::size(arr)。
#define BIT(n) (1U << (n))
#define SET_BIT(reg, n) ((reg) |= BIT(n))
#define CLEAR_BIT(reg, n) ((reg) &= ~BIT(n))
#define TEST_BIT(reg, n) (((reg) & BIT(n)) != 0)
#define TOGGLE_BIT(reg, n) ((reg) ^= BIT(n))
#define INIT_STRUCT(type, ...) (type){ __VA_ARGS__ }
配合 .member = value 寫法,順序無關、可選初始化。
#define SQR(x) ((x)*(x))。#define ADD(a,b) ((a)+(b))。do { ... } while(0) 包裹。static inline 函數(型別檢查、除錯可見、無副作用)。巨集是 C 語言的雙面刃:善用可極大提升表達力與效能,濫用則製造難以除錯的災難。建議將上述常用模式收錄至專案共用 macros.h,團隊統一風格。