Почему я не получаю ошибку компиляции при объявлении массива C с переменным размером? - PullRequest
6 голосов
/ 30 марта 2009

Я всегда понимал, что когда я объявляю массив в стеке с размером, который входит в качестве переменной или параметра, я должен получить ошибку.

Однако я заметил, что не получаю никакой ошибки, если не буду явно инициализировать массив (да, он не будет в стеке, но меня интересует отсутствие ошибки). Например, следующий код не компилируется из-за array2:

#define N 30

void defineArrays(int n)
{
    int i,j;
    int array1[N] = {};

    int array2[n] = {};

    for(i=0; i<N; ++i) array1[i] = 0;

    for(j=0; j<n; ++j) array2[j] = 0;
}

Но следующий код компилируется и запускается, даже когда я посылаю реальный n из main:

#define N 30

void defineArrays(int n)
{
    int i,j;
    int array1[N] = {};

    int array2[n];

    for(i=0; i<N; ++i) array1[i] = 0;

    for(j=0; j<n; ++j) array2[j] = 0;
}

Что мне здесь не хватает? Объявляет ли array2 как указатель? Я использую GCC

Обновление: спасибо всем, кто ответил. Проблема заключалась в том, что моя версия gcc по умолчанию была C99 по какой-то странной причине (или не настолько странной, может быть, я просто слишком стар), и я неправильно предположил, что по умолчанию C90, если я не скажу иначе.

Ответы [ 4 ]

14 голосов
/ 30 марта 2009

C99 представил возможность иметь массивы переменной длины, которые теперь доступны в GCC (хотя сообщается, что они не полностью соответствуют стандартам). Во втором примере вы, кажется, пользуетесь этой функциональностью.

Ссылка на информацию GCC о массивах переменной длины: http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

3 голосов
/ 30 марта 2009

Я думаю, что вам нужно выбрать стандартную версию C.

gcc -fsyntax-only -std=c89 -pedantic -x c -

<stdin>: In function ‘defineArrays’:
<stdin>:6: warning: ISO C forbids empty initializer braces
<stdin>:8: warning: ISO C90 forbids variable length array ‘array2’

против

gcc -fsyntax-only -std=c99 -pedantic -x c -
<stdin>: In function ‘defineArrays’:
<stdin>:6: warning: ISO C forbids empty initializer braces
1 голос
/ 30 марта 2009

Когда я компилирую первый пример с помощью gcc, он выдает мне эту ошибку:

error: variable-sized object may not be initialized

Я полагаю, что это запрещено, потому что вы не знаете, насколько большим будет n, и поэтому вы не можете быть уверены, что он будет достаточно большим, чтобы вместить все элементы, которые вы пытаетесь инициализировать. То есть предположим, что у вас есть такой код:

int array2[n] = { 1, 2, 3, 4 };

Для этого необходимо, чтобы массив2 имел (как минимум) 4 слота. Что делать, если n передается как ноль?

Во втором примере такой проблемы нет, поскольку вы не делаете никаких неявных утверждений о размере массива 2.

Надеюсь, это поможет,

Эрик Мелски

1 голос
/ 30 марта 2009

Объявление массива с помощью инициализатора заставляет массив быть статическим (созданным во время компиляции), даже если область действия находится внутри функции. Компилятор не может определить массив во время компиляции, потому что он не знает значение 'n'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...