2010-09-23 3 views
15

Что происходит в C при создании массива отрицательной длины?Объявление массива отрицательной длины

Например:

int n = -35; 

int testArray[n]; 

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

Этот код будет скомпилирован (и не вызывает никаких предупреждений с -Wall включена), и, кажется, вы можете назначить testArray[0] без проблем. Присваивая прошлое, которое дает либо ошибку segfault, либо незаконную инструкцию, и чтение чего-либо из массива говорит «Abort trap» (я не знаком с этим). Я понимаю, что это несколько академический, и (надеюсь) никогда не появятся в реальной жизни, но есть ли какой-то особый способ, который стандарт C говорит, чтобы рассматривать такие массивы, или это зависит от компилятора от компилятора?

+0

Существует непреднамеренная точка с запятой (';') в конце инструкции 'for', я думаю ... – Arun

+0

Спасибо, я исправил ее! – jonmorgan

ответ

20

Это неопределенное поведение, так как он нарушает «должен» ограничение:

C99 §6.7.5.2:

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

+0

Спасибо! Это именно то, что я искал. – jonmorgan

+2

+1, точно ответ. Но я нахожу довольно разочаровывающим, что компиляторы еще не в состоянии выполнить статический анализ такого кода и испускать хотя бы предупреждение. Я тестировал также «clang» и «-analyse», не лучше. –

3

Неопределенное поведение, я считаю, хотя и не цитирую меня.

Это дает ошибку error: size of array 'testArray' is negative в НКУ:

int testArray[-35]; 

, хотя, как вы уже видели:

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

не дает ошибку, даже с обоими -Wall и -W.

Однако, если вы используете -pedantic flag, gcc предупредит, что ISO C90 запрещает массив переменной длины.

+0

Что это на самом деле? Я предполагаю, что он интерпретирует его как unsigned, поэтому вы получаете (MAX_INT-35) –

+1

@Martin Beckett: поскольку это неопределенное поведение, компиляторы могут делать что угодно, даже если это необоснованное поведение, так как выделение массива отрицательной длины является компилируемая ерунда. Если бы мне разрешили перепроектировать C, я бы сделал объявление длины массива и индексировал «unsigned int», и компилятор должен был испускать ошибку типа, когда «signed int» используется для операций длины или индексирования. –

+0

вопрос был отмечен C99, поэтому аспект массива переменной длины одобрен со стандартной точки зрения. –

0

Visual studio erro message для compilation, вы можете использовать -1, чтобы сказать пустой массив. Он ожидает int и вы передаете int, поэтому ошибки компилятора.

Смежные вопросы