2013-07-09 2 views
5

Я программирую на C99 и использую массивы переменной длины в одной части моего кода. Я знаю, что в C89 массивы нулевой длины не разрешены, но я не уверен в C99 и массивах переменной длины.Имеются ли допустимые/корректные массивы переменной длины с нулевой длиной?

Короче говоря, следующее четко определенное поведение?

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

Это не должно даже компилироваться, поскольку «i' не является константой времени компиляции. – Jashaszun

+1

попробуйте компилировать это; gcc выйдет, ударит вас, расстрелят и украдут вашу машину. –

+4

[Ребята ...это C99 ... не C89.] (http://ideone.com/NKtfJD) – Cornstalks

ответ

13

Нет, нулевую длину массивы явно запрещены языком C, даже если они созданы как VLA по значению размера времени выполнения (как в вашем примере коды).

6.7.5.2 Массив declarators

...

Если размер является выражением, которое не является постоянным выражения целого: если это происходит в объявлении в функции область прототипа, обрабатывается так, как если бы она была заменена на *; в противном случае, каждый раз, когда он оценивается , он должен иметь значение больше нуля.

+0

Oooo, yay, цитаты из стандарта. Мне это нравится. +1! – Cornstalks

2

нулевой длины массивы не допускаются в С. статически типизированных массивы должны иметь фиксированный, ненулевой размер, который является постоянным выражением, и переменной длины-массивы должны иметь размер, который оценивает ненулевое значение; С11 6.7.6.2/5:

каждый раз, когда он [выражение размера] вычисляется оно должно иметь значение больше нуля

Однако, С99 и С11 имеют понятие гибкого массива член из структуры:

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

от С11, 6.7.21/18:

В качестве особого случая последний элемент структуры с более чем одним именованным элементом может иметь , имеющий неполный тип массива; это называется элементом гибкой матрицы. В большинстве ситуаций элемент гибкого массива игнорируется. В частности, размер структуры выглядит так, как если бы элемент гибкой решетки был исключен, за исключением того, что он может иметь более длинную прокладку, чем , что подразумевает упущение. Однако, когда оператор . (или ->) имеет левый операнд, который представляет собой (указатель на) структуру с гибким членом массива и именами правого операнда, который имеет член , он ведет себя так, как если бы этот элемент был заменен самым длинным массивом (с тем же типом типа ), который не сделает структуру больше, чем объект, к которому обращаются;

+0

Спасибо за примечание о гибком элементе массива. Эта цитата из стандарта была действительно полезна! – Cornstalks

1

В стандартной комплектации C (даже C99 или C11) не допускаются массивы нулевой длины. Но gcc предоставляет расширение, чтобы разрешить это. См. http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

struct line { 
    int length; 
    char contents[0]; 
}; 

struct line *thisline = (struct line *) 
    malloc (sizeof (struct line) + this_length); 
thisline->length = this_length; 
Смежные вопросы