第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

拒絕指針的數(shù)組大小的宏

拒絕指針的數(shù)組大小的宏

C
RISEBY 2019-10-18 09:53:14
通常講授的標(biāo)準(zhǔn)數(shù)組大小宏是#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))或某些等效形式。但是,當(dāng)傳入一個指針時,這種事情會悄無聲息地成功,并且給出的結(jié)果在運(yùn)行時看起來似乎是合理的,直到事情神秘地消失。犯這樣的錯誤太容易了:重構(gòu)具有局部數(shù)組變量的函數(shù),將數(shù)組操作的一部分移到以數(shù)組為參數(shù)的新函數(shù)中。因此,問題是:是否存在“衛(wèi)生的”宏來檢測ARRAYSIZEC中宏的濫用,最好是在編譯時?在C ++中,我們將僅使用專門用于數(shù)組參數(shù)的模板。在C語言中,似乎我們需要某種方式來區(qū)分?jǐn)?shù)組和指針。(例如,如果我想拒絕數(shù)組,我會做例如(arr=arr, ...)因為數(shù)組分配是非法的)。
查看完整描述

3 回答

?
ITMISS

TA貢獻(xiàn)1871條經(jīng)驗 獲得超8個贊

Linux內(nèi)核使用了一個不錯的實(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中是可移植的,因為它使用了兩個內(nèi)在原理:  typeof運(yùn)算符和__builtin_types_compatible_p函數(shù)。它還使用BUILD_BUG_ON_ZERO僅在GNU C中有效的“著名” 宏。


假設(shè)有一個編譯時評估要求(這就是我們想要的),我不知道該宏的任何可移植實(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ù)是一個數(shù)組這個沒有給出警告,-std=c99 -Wall但-pedantic會發(fā)出警告。原因是IS_ARRAYexpression不是整數(shù)常量表達(dá)式(整數(shù)常量表達(dá)式中不允許轉(zhuǎn)換為指針類型和下標(biāo)運(yùn)算符),并且in的位字段寬度STATIC_EXP需要整數(shù)常量表達(dá)式。


查看完整回答
反對 回復(fù) 2019-10-18
?
PIPIONE

TA貢獻(xiàn)1829條經(jīng)驗 獲得超9個贊

此版本的ARRAYSIZE()return 0when arr是指針,而其大小是純數(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)行時異常(除以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í)行編譯時錯誤(arg必須在運(yùn)行時比較的地址)


查看完整回答
反對 回復(fù) 2019-10-18
  • 3 回答
  • 0 關(guān)注
  • 527 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號