2017-02-20 66 views
1

當數組爲空時,ARRAY_SIZE是否返回未定義的行爲?因爲我們做了一個未知的分區sizeof((X)[0])當數組爲空時,ARRAY_SIZE是否返回未定義的行爲?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#ifndef ARRAY_SIZE 
#define ARRAY_SIZE(X) sizeof((X))/sizeof((X)[0]) 
#endif 

struct ka { 
    int a; 
    int b; 
}; 

int main(void) 
{ 
    struct ka k[] = {}; 
    printf("%d\n", ARRAY_SIZE(k)); 
} 
+4

這不是C++。對於未指定的數組,空數組初始化器被禁止 – mpiatek

+0

由於'sizeof(k [0])'實際上不訪問任何內存,所以這不是UB。它與'sizeof(ka)' – rustyx

回答

3

標準C或C++中不可能有零大小的數組。

在C中,您的代碼違反了約束條件(空白初始化程序列表在任何地方都是不允許的)。

在C++中它也是一個錯誤; {}可能不能用於忽略大小的數組定義。 (C++ 14 [dcl.init.aggr]/4)

如果使用非標準的編譯器擴展,則行爲將取決於該擴展的詳細信息。

+0

完全一樣,我用gcc編譯,它不會返回錯誤C既不是警告 – MOHAMED

+2

爲什麼它被零除錯誤? 'sizeof((X)[0])'是'sizeof(struct ka)',它不是'0'。 – mch

+1

@MOHAMED gcc默認爲GNU擴展模式。對於C,使用編譯開關'-std = c11 -pedantic',或者對於C++使用'std = C++ 14 -pedantic'來獲得標準行爲。 –

1

一般而言,從用於存儲器訪問的點,這是好的,因爲,除非的sizeof操作數是VLA型的,它們是不評價。因此,在這種情況下,x[0]不是無效的內存訪問。

引用C11,章§6.5.3.4,重點煤礦

sizeof操作者產生其操作數的大小(以字節爲單位),其可以是 表達或類型的括號的名稱。大小由操作數的類型 決定。結果是一個整數。如果操作數的類型是可變長度數組 類型,則評估操作數; 否則,操作數不會被評估爲,結果是一個整數常量 。

在廣義上,對於像

int arr[5]= {0}; 

陣列寫入

sizeof(arr)/sizeof(arr[10]); 

有效arr[10]沒有被評估,這只是關於操作數的大小,而不是內容(所以,不需要解引用)。

這就是說,

  • 零長度數組是沒有標準的C,它們是gcc extension
  • sizeof得到的結果大小爲size_t,所以我們應該使用%zu格式說明符來打印結果。
+0

被評估的內容與它有什麼關係 –

+1

@ M.M解引用無效內存? –

+0

哦,我明白了,他擔心x [0]可能是超出界限的訪問。 –

相關問題