2013-07-09 24 views
5

Programuję w C99 i używam tablic o zmiennej długości w jednej części mojego kodu. Wiem, że tablice zerowej długości C89 są niedozwolone, ale nie jestem pewien co do tablic C99 i zmiennej długości.Czy tablice o zmiennej długości o zerowej długości są dozwolone/dobrze zdefiniowane?

Krótko mówiąc, czy występuje następujące dobrze zdefiniowane zachowanie?

int main() 
{ 
    int i = 0; 
    char array[i]; 
    return 0; 
} 
+0

To nie powinno nawet się kompilować, ponieważ 'i' nie jest stałą czasu kompilacji. – Jashaszun

+1

spróbuj skompilować; gcc wyjdzie, uderzy cię, zastrzeli i ukradnie twój samochód. –

+4

[Faceci ...to jest C99 ... nie C89.] (http://ideone.com/NKtfJD) – Cornstalks

Odpowiedz

13

Nie, tablice zerowej długości są wyraźnie zakazane przez języku C, nawet jeśli są one tworzone jako VLA przez wartości wielkości run-time (jak w próbce kodu).

6.7.5.2 Array declarators

...

Jeśli rozmiar jest wyrazem, który nie jest liczbą całkowitą stałą wyrażenie: jeśli występuje w deklaracji w funkcji prototypowy zakres, jest traktowany tak, jakby został zastąpiony przez *; w przeciwnym razie, za każdym razem, gdy jest oceniany jako , będzie mieć wartość większą od zera.

+0

Oooo, yay, cytaty ze standardu. Lubię te. +1! – Cornstalks

2

zerowej długości tablice nie są dozwolone C statycznie wpisane macierze muszą mieć, nie-zerową wielkość, która jest stała ekspresja i zmiennej długości macierze muszą mieć rozmiar, który ocenia różną od zera; C11 6.7.6.2/5:

każdym razem [wyrażenie rozmiar] ocenia powinny mieć wartości większej niż zero

Jednakże, C99 i C11 mają pojęcie elastycznej matrycy członek od struct:

struct foo 
{ 
    int a; 
    int data[]; 
}; 

od C11, 7.6.21/18:

W szczególnym przypadku ostatni element struktury z więcej niż jednym nazwanym elementem może mieć niekompletny typ tablicy; nazywa się to elastycznym elementem tablicy . W większości sytuacji, elastyczny element tablicy jest ignorowany. W szczególności rozmiar struktury jest taki, jak gdyby pominięto elastyczny człon matrycowy , z tym wyjątkiem, że może on mieć więcej padania z tylną ścianką niż to oznaczałoby pominięcie. Jednak gdy operator . (lub ->) ma lewy operand, który jest (wskaźnik na) strukturę z elastycznym elementem macierzy i prawymi argumentami operandowymi, który jest członkiem , zachowuje się tak, jakby ten element był zamieniany na najdłuższy zestaw (z tym samym typem elementu ), który nie powodowałby, że struktura była większa niż obiekt, do którego uzyskiwany był dostęp;

+0

Dzięki za uwagę na temat elastycznego elementu tablicy. Ten cytat ze standardu był naprawdę użyteczny! – Cornstalks

Powiązane problemy