結合複雜的宏具有多級預處理可以工作 -
這實現了「最多5個輸入」的預期目標。
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
#define macro_dispatcher__(func,nargs) funC## nargs
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define sizeof_max(...) macro_dispatcher(sizeof_max, __VA_ARGS__)(__VA_ARGS__)
#define sizeof_max1(a) (sizeof(a))
#define sizeof_max2(a,b) (sizeof(a)>sizeof(b)?sizeof(a):sizeof(b))
#define sizeof_max3(a,b,c) sizeof_max2(sizeof_max2(a,b), c)
#define sizeof_max4(a,b,c,d) sizeof_max2(sizeof_max3(a,b,c),d)
#define sizeof_max5(a,b,c,d,e) sizeof_max2(sizeof_max4(a,b,c,d),e)
這將爲GCC/C99工作。這是問題的解決方案,我在這裏發帖是因爲我從中學到了很多東西,並且想分享它。這就是說,閱讀免責聲明結束:)。
參考
使用macro_dispatcher的()由 'RMN' 從efesx論壇在這裏提供:
添加FCN#函數名也描述在這裏:
當然,這裏有一些GCC可變參數宏網頁:
例
typedef union {
uint8_t array[sizeof_max(A,B,C)]; //array is of size 10.
A iso_hugenum_a;
B ext_a0;
C ext_a1;
} DATA_SEG;
擊穿
你可以嘗試在 'main.c中' 這個代碼,選擇 'GCC-E的main.c' 編譯觀察宏觀內斯:
int main (void) {
uint8_t rslt;
//preprocs to 'rslt=C;'
rslt = VA_NUM_ARGS_IMPL(A,B,C,A,B,C,A);
//preprocs to 'rslt=3'
rslt = VA_NUM_ARGS(A,B,C);
//preprocs to 'rslt=maxN'
rslt = macro_dispatcher__(max, N);
//preprocs to 'rslt=macro_dispatcher_(max, N);'
rslt = macro_dispacther_(max, N);
//preprocs to 'rslt=max3;'
rslt = macro_dispatcher(max, X, Y, Z);
//preprocs to 'sizeof_max1(A)/max2(A,B)/max3(A,B,C)'
rslt = sizeof_max(A);
rslt = sizeof_max(A,B);
rslt = sizeof_max(A,B,C);
//Breakdown:
//sizeof_max(A,B,C);
//macro_dispatcher(sizeof_max, __VA_ARGS__)(__VA_ARGS__)
//macro_dispatcher_(sizeof_max, 3)(__VA_ARGS__)
//macro_dispatcher__(sizeof_max,3)(__VA_ARGS__)
//
//Result:
//sizeof_max3(__VA_ARGS__)
//sizeof_max3(A,B,C)
rslt = sizeof_max(A,B,C);
return 0;
}
(免責聲明)更簡單&更安全永遠贏。因此,我很可能會選擇離克利福德最近的答案。沒有必要讓我玩一些可愛的技巧,這些技巧會讓其他人「一字不漏」。
爲什麼你不能只使用'sizeof'一些'union',就像你的'DATA_SEG' *沒有*'array'一樣? –
這不就是'union'的正常用例嗎? –
刪除了C++標籤;謝謝。 –