sizeof 是 C++ 中極具特殊性的關鍵字。它在編譯期求值,結果為常量表達式。理解其「編譯期替換」本質,是避開經典陷阱(如副作用不執行)的關鍵。本文將系統講解其定義、兩種語法形式、類型推導規則與實戰陷阱。
char 大小,即 1 字節)。std::size_t (無符號整型)。sizeof(...) 直接替換為常數。| 形式 | 語法 | 示例 | 說明 |
|---|---|---|---|
| 操作數為類型 | sizeof(類型名) | sizeof(int), sizeof(MyClass) | 必須加括號。sizeof int 非法。 |
| 操作數為表達式 | sizeof 表達式 或 sizeof(表達式) | sizeof x, sizeof(x), sizeof(1+2) | 括號可選但建議始終加上,避免歧義。 |
黃金法則:無論對類型還是表達式,統一使用 sizeof( ... ) 形式,永遠正確且清晰。
這是最核心、最易踩坑的特性。
int a = 0;
std::cout << sizeof(a = 3) << std::endl; // 輸出 4 (int 大小)
std::cout << a << std::endl; // 輸出 0 !!! 賦值未執行
原因:編譯器只分析表達式 a = 3 的類型(賦值表達式類型為左值類型 int),直接替換為 4。賦值指令從未生成機器碼。
sizeof(int) // 4 (32位系統)
sizeof(1 == 2) // 1 (bool 類型,== 返回 bool)
sizeof('c') // 4 (字符字面量類型為 int,C++ 特性)
sizeof("str") // 4/8 (字符串字面量類型為 const char[N],退化為指針)
// 注意:sizeof 對數組名不退化
int arr[10];
sizeof(arr) // 40 (int[10] 完整類型大小)
sizeof(&arr) // 4/8 (指針大小)
一元運算符可鏈式:++++i (雖無意義但合法)。sizeof 不行:
// sizeof sizeof int // 編譯錯誤
// 原因:sizeof 後需跟類型或表達式,sizeof int 本身非類型/表達式
static_assert(sizeof(MyStruct) == 16, "Alignment broken");int n = sizeof(arr) / sizeof(arr[0]); (僅適用於作用域內的真數組,不適用指針)。#pragma pack 或屬性效果。alignof(T):獲取類型對齊要求 (編譯期常量),配合 sizeof 完整描述內存佈局。std::size(arr) (C++17, <iterator>):安全獲取數組/容器大小,替代宏。std::byte (C++17):字節操作類型,語義比 char/unsigned char 更清晰。sizeof 是編譯期的「類型尺子」。牢記三點:1. 編譯期求值,表達式不執行;2. 統一用 sizeof(...) 語法;3. 結果為 size_t 常量表達式。 理解其本質,能寫出更安全的泛型代碼、元編程邏輯與內存佈局控制代碼。