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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

拒絕指針的數(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)傳入一個(gè)指針時(shí),這種事情會(huì)悄無聲息地成功,并且給出的結(jié)果在運(yùn)行時(shí)看起來似乎是合理的,直到事情神秘地消失。犯這樣的錯(cuò)誤太容易了:重構(gòu)具有局部數(shù)組變量的函數(shù),將數(shù)組操作的一部分移到以數(shù)組為參數(shù)的新函數(shù)中。因此,問題是:是否存在“衛(wèi)生的”宏來檢測ARRAYSIZEC中宏的濫用,最好是在編譯時(shí)?在C ++中,我們將僅使用專門用于數(shù)組參數(shù)的模板。在C語言中,似乎我們需要某種方式來區(qū)分?jǐn)?shù)組和指針。(例如,如果我想拒絕數(shù)組,我會(huì)做例如(arr=arr, ...)因?yàn)閿?shù)組分配是非法的)。
查看完整描述

3 回答

?
ITMISS

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á)式。


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

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í)比較的地址)


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

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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