看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《liptonbin (wind)》之銘言: : 請問一下 : #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + : __must_be_array(arr)) : 其中他的定義如下 : #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) : #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) : #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) : 不曉得有沒有人看得懂BUILD_BUG_ON_ZERO和__same_type各式作什麼的 : 為什array_size需要多加 __must_be_array(arr) : 謝謝 原本的確 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 就可以了 但怕你 arr 代入的是 pointer(*) 而不是 array([]),所以用一些技巧來避免誤用的情況 看底下例子: #include <stdio.h> #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) int main(){ int array[20]; int *ptr = array; /* 這裡代入的是 int * ,而不是 int [20] */ printf("%lu\n",ARRAY_SIZE(ptr)); return 0; } 印出來的結果應該不是你想要的 20 XD ========= 以下來看上面那些 macro 在做啥事 ========= 1. #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) 其中 __builtin_types_compatible_p (type1, type2) 是 built-in function provided by GCC,用途是比較 type1 跟 type2 是不是 compatible,如果 compatible 則回傳 1 否則為 0 2. #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) 展開之後變成,BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&(a)[0]))),剛剛前面有提到 __builtin_types_compatible_p 只會回傳 0 或 1 註: a 如果是 array([]) 則 __builtin_types_compatible_p(typeof(a), typeof(&(a)[0])) 會回傳 0;a 如果是 pointer(*) 則回傳 1 所以 __must_be_array(a) 替換後不是 BUILD_BUG_ON_ZERO(0) 就是 BUILD_BUG_ON_ZERO(1) 3. #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) 把 BUILD_BUG_ON_ZERO(0) 替換會得到: sizeof(struct { int:0; }) <== 合法,會得到 0 把 BUILD_BUG_ON_ZERO(1) 替換會得到: sizeof(struct { int:-1; }) <== 不合法,bit-field 的 width 不能為負, 所以 compile 會報錯,也利用這一點來達到靠 compile 來避免誤用的情況 ========= 結論 ========= 以上是我 google 英、簡、中說明加上做些小實驗後的理解,哈哈XD -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 210.59.164.109
angleevil:樓上是神 11/02 16:55
LPH66:話說這讓我想到 VC2005 的 _countof... (ref.#18GQ0GzF) 11/02 17:01
LPH66:那個用的方法需要一點 template 的概念才看得懂 XD" 11/02 17:02
hilorrk:static assertion? 11/02 19:30
poyenc:之前沒發現的現象 http://boost.codepad.org/93baR82G XD 11/02 20:53
hilorrk:cool! 11/02 21:38
VictorTom:推, 太強大了Orz 11/02 23:09
tropical72:cutecpu 好強!! 補一下, struct {int:0;} 大小應不是 11/02 23:31
tropical72:確定的,depends on compiler ? 11/02 23:31
hilorrk:「大小不確定」的說法不太正確,因為0-width bit-field是 11/03 00:29
hilorrk:align,由於它一定是unnamed(沒有declarator) 所以也沒有 11/03 00:31
hilorrk:大小可言...要說的話 說是零或大小不定都對 11/03 00:32
tropical72:先謝謝h大補充,但不知是不是vc關係,上述是 error C2149 11/03 01:17
tropical72:sori! 請無視樓上,可過(4bytes),have a warnning. 11/03 01:22
cobrasgo:好強大… 11/03 03:14