3 回答

TA貢獻(xiàn)1871條經(jīng)驗(yàn) 獲得超8個(gè)贊
Linux內(nèi)核使用了一個(gè)不錯(cuò)的實(shí)現(xiàn)ARRAY_SIZE來解決此問題:
#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 __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
當(dāng)然,這僅在GNU C中是可移植的,因?yàn)樗褂昧藘蓚€(gè)內(nèi)在原理: typeof運(yùn)算符和__builtin_types_compatible_p函數(shù)。它還使用BUILD_BUG_ON_ZERO僅在GNU C中有效的“著名” 宏。
假設(shè)有一個(gè)編譯時(shí)評(píng)估要求(這就是我們想要的),我不知道該宏的任何可移植實(shí)現(xiàn)。
“半便攜式”實(shí)現(xiàn)(并且不能涵蓋所有情況)是:
#define ARRAY_SIZE(arr) \
(sizeof(arr) / sizeof((arr)[0]) + STATIC_EXP(IS_ARRAY(arr)))
與
#define IS_ARRAY(arr) ((void*)&(arr) == &(arr)[0])
#define STATIC_EXP(e) \
(0 * sizeof (struct { int ARRAY_SIZE_FAILED:(2 * (e) - 1);}))
隨著gcc如果參數(shù)是一個(gè)數(shù)組這個(gè)沒有給出警告,-std=c99 -Wall但-pedantic會(huì)發(fā)出警告。原因是IS_ARRAYexpression不是整數(shù)常量表達(dá)式(整數(shù)常量表達(dá)式中不允許轉(zhuǎn)換為指針類型和下標(biāo)運(yùn)算符),并且in的位字段寬度STATIC_EXP需要整數(shù)常量表達(dá)式。

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超9個(gè)贊
此版本的ARRAYSIZE()return 0when arr是指針,而其大小是純數(shù)組時(shí)的大小
#include <stdio.h>
#define IS_INDEXABLE(arg) (sizeof(arg[0]))
#define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
#define ARRAYSIZE(arr) (IS_ARRAY(arr) ? (sizeof(arr) / sizeof(arr[0])) : 0)
int main(void)
{
int a[5];
int *b = a;
int n = 10;
int c[n]; /* a VLA */
printf("%zu\n", ARRAYSIZE(a));
printf("%zu\n", ARRAYSIZE(b));
printf("%zu\n", ARRAYSIZE(c));
return 0;
}
輸出:
5
0
10
正如本杰克遜(Ben Jackson)指出的那樣,您可以強(qiáng)制運(yùn)行時(shí)異常(除以0)
#define IS_INDEXABLE(arg) (sizeof(arg[0]))
#define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))
#define ARRAYSIZE(arr) (sizeof(arr) / (IS_ARRAY(arr) ? sizeof(arr[0]) : 0))
可悲的是,您不能強(qiáng)制執(zhí)行編譯時(shí)錯(cuò)誤(arg必須在運(yùn)行時(shí)比較的地址)
- 3 回答
- 0 關(guān)注
- 511 瀏覽
添加回答
舉報(bào)