2010-09-23 99 views
15

當你創建一個負數的數組時,會發生什麼?聲明一個負數長度的數組

例如:

int n = -35; 

int testArray[n]; 

for(int i = 0; i < 10; i++) 
    testArray[i]=i+1; 

該代碼將編譯(並帶來了-Wall沒有警告啓用),似乎可以分配給testArray[0]沒有問題。指定過去會導致段錯誤或非法指令錯誤,並且從數組中讀取任何內容都會顯示「中止陷阱」(我對此不熟悉)。我意識到這有些學術性,並且(希望)從未在現實生活中出現過,但是C標準對待這種數組有沒有什麼特別的方式呢?還是從編譯器到編譯器有所不同?

+0

在'for'語句末尾有一個意想不到的分號(';'),我想...... – Arun 2010-09-24 00:14:09

+0

謝謝,我修好了! – jonmorgan 2010-09-24 00:22:30

回答

20

這是不確定的行爲,因爲它打破了「應當」的約束:

C99§6.7.5.2:

如果大小是 不是一個整數常量表達式的表達式。 ... ...每次評估它應該 有一個大於零的值。

+0

謝謝!這正是我所期待的。 – jonmorgan 2010-09-24 00:28:26

+2

+1,正是答案。但是我發現編譯器還不能對這類代碼進行靜態分析併發出至少一個警告,這令人非常失望。我也用'clang'和'-analyse'測試過,不是更好。 – 2010-09-24 07:53:33

3

未定義的行爲,我相信,但不要在此引用我的意思。

這給了錯誤error: size of array 'testArray' is negative在GCC:

int testArray[-35]; 

不過,因爲你已經看到:

int n = -35; 
int testArray[n]; 

不再用-Wall和-W甚至給出錯誤。

但是,如果您使用-pedantic標誌,gcc會警告ISO C90禁止變長數組。

+0

它實際上做了什麼?我猜它認爲它是無符號的,所以你得到(MAX_INT-35) – 2010-09-24 00:52:19

+1

@Martin Beckett:由於它是未定義的行爲,編譯器可以自由地做任何事情,即使它們是不合理的行爲,因爲分配一個負長度數組是一個可編輯的廢話。如果我被允許重新設計C,我會進行數組長度聲明並索引一個'unsigned int',並且當'signed int'用於長度或索引操作時,需要編譯器發出類型錯誤。 – 2010-09-24 02:32:31

+0

這個問題被標記爲C99,因此從標準的角度來看,可變長度數組的方面是可以的。 – 2010-09-24 07:50:38

0

對於compilation的Visual Studio錯誤消息,可以使用-1來表示空數組。它期望int,你傳遞int,所以沒有編譯器錯誤。