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

Chrome 原始碼中的編譯期陣列大小計算模板技巧解析

     編輯:關於C語言

神奇的模板代碼


template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];

#define arraysize(array) (sizeof(ArraySizeHelper(array)))

原理逐層拆解

  1. T (&array)[N]:函式參數為陣列引用,編譯器能推導出類型 T 與大小 N
  2. 回傳型別 char (&)[N]:字元陣列引用,大小同樣為 N
  3. sizeof(ArraySizeHelper(array)):對引用取 sizeof 得到被引用物件大小,即 sizeof(char[N]) = N

整個過程在編譯期完成,零執行期開銷。

為何不用傳統巨集?

#define arraysize(array) (sizeof(array)/sizeof(array[0]))

傳統寫法雖簡單,但無法防止指標退化:若傳入指標而非陣列,sizeof(pointer)/sizeof(pointer[0]) 會得到錯誤結果(通常為 1 或 4/8)。Chrome 的模板版本只接受陣列引用,傳入指標會編譯失敗,從源頭杜絕誤用。

實測範例


double a[200];
double* b = new double[100];

int cnt1 = arraysize(a);  // 200 ✓
// int cnt2 = arraysize(b);  // 編譯錯誤:無法推導 N

適用範圍與限制

  • ✅ 靜態陣列、堆疊陣列、結構體成員陣列
  • ❌ 動態配置陣列(new T[n])、函式參數退化為指標的情況
  • ❌ C99 可變長度陣列(VLA,C++ 不支援)

現代 C++ 替代方案

C++17 起可用 std::size(arr)(<iterator>),同樣編譯期計算、拒絕指標、支援所有容器,為標準化解法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved