2011-05-30 139 views
28

今天我偶然定義了一維爲0的二維數組,但是我的編譯器沒有發出抱怨。我發現其中指出,這是合法的,至少在海灣合作委員會的情況如下:大小爲0的數組

6.17 Arrays of Length Zero

不過,我對這個用法兩個問題:

首先,這被認爲是良好的編程實踐?如果是這樣,那麼我們應該什麼時候在真實世界中使用它?

其次,我定義的數組是二維的,一維爲0。這與一維情況相同嗎?例如,

int s[0] 
int s[0][100] 
int s[100][0] 

它們在內存和編譯器中都是一樣的嗎?

編輯:回覆Greg:我使用的編譯器是gcc 4.4.5。我對這個問題的意圖不是依賴於編譯器,但是如果有任何編譯器具體的怪癖,這將有所幫助:)

在此先感謝!

+0

鑑於您已經在您的問題中引用了編譯器,它將有助於提供有關您所關注的特定編譯器的信息。 – Greg 2011-05-30 19:28:01

+1

請檢查此問題http://stackoverflow.com/questions/295027/array-of-zero-length – vasin 2011-05-30 19:30:21

+0

請注意,對於C++ 11,「std :: array」類型[可能具有0的大小](http: //en.cppreference.com/w/cpp/container/array)(但普通數組必須至少有一個元素)。 – Cameron 2013-08-24 19:02:36

回答

26

在C++中聲明一個長度爲零的數組是非法的。因此,當您將代碼綁定到特定的編譯器擴展時,它通常不被認爲是一種好的做法。動態大小的數組的許多用法更好地替換爲容器類,如std::vector

ISO/IEC 14882:2003 8.3.4/1:

如果常數表達式(5.19)時,它應是一個積分常數的表達及其值應大於零。

但是,您可以使用new[]動態分配零長度的數組。

ISO/IEC 14882:2003 5.3.4/6:

直接新聲明符表達應具有與非負值整數或枚舉類型(3.9.1) 。

+1

查爾斯無法理解你可以動態分配一個零長度的數組,你能詳細說明這一點。 – 2015-01-09 14:46:52

+2

@Krishna_Oza你可以這樣做:'int * x = new int [0];'它會返回一個指針,但取消引用它是未定義的,因爲沒有可能的理由這樣做。編譯器可以對其進行解引用,包括崩潰程序。 – smead 2016-02-26 05:27:51

4

我在ideone.com

#include <iostream> 

int main() 
{ 
    int a[0]; 
    int b[0][100]; 
    int c[100][0]; 

    std::cout << "sizeof(a) = " << sizeof(a) << std::endl; 
    std::cout << "sizeof(b) = " << sizeof(b) << std::endl; 
    std::cout << "sizeof(c) = " << sizeof(c) << std::endl; 

    return 0; 
} 

運行這個程序它給了所有變量的大小爲0

sizeof(a) = 0 
sizeof(b) = 0 
sizeof(c) = 0 
在上面的例子中

所以,沒有內存分配abc

+0

在答案中,您可以添加執行的編譯器,因爲您指定的鏈接不顯示代碼。 – 2015-01-09 14:48:45

+0

@Krishna_Oza ideone.com自2015-10-20起使用gcc 5.1,它是少數幾個支持空數組的編譯器之一(我發現在將大小不同的數組傳遞給函數時,我發現它非常便於進行泛型測試,包括空虛作爲有效的測試用例)。 – 2015-10-20 08:38:16

2

用gcc編譯你的例子,它們全部三個都有sizeof 0,所以我會假設它們都被編譯器同等對待。

+1

這將是一個編譯器錯誤*,而不是供應商擴展。 C++要求所有的對象必須至少有一個字節的大小,所以它們得到唯一的地址。 – 2011-05-30 19:45:29

+0

@ Ben Voigt:從原始海報提供的鏈接中可以看出,gcc明確允許長度爲零的數組並不是一個錯誤。 – Kanopus 2011-05-30 19:57:14

+0

這是一個錯誤。供應商在接受代碼時有很大的餘地,標準沒有爲行爲定義,但是當他們這樣做時,他們仍然需要遵循適用的任何標準規則。該標準要求每個對象都有唯一的地址和嚴格的正面大小。子對象需要一個不同於不是父對象的每個對象的地址。 – 2011-05-30 20:50:20

2

您的鏈接解釋了一切。當在編譯時不知道struct的長度時,它們被用作結構中的最後一個字段。如果您嘗試在堆棧或其他聲明中使用它們,您最終會覆蓋下一個元素。

相關問題