C - Недопустимый синтаксис, разрешенный компилятором?

Когда я изучал C с помощью Microsoft Visual Studio, он не позволял мне создавать массив непостоянного размера. Мне нужно было либо поставить значение вроде int arr[5];, либо сделать #define size 5 и сделать int arr[size];. Однако сегодня, используя Clion, я заметил, что он позволяет мне делать следующее:

#include <stdio.h>

int main()
{
    printf("Enter a value: ");
    int x;
    scanf("%d", &x);

    int arr2[x];
    for (int i = 0; i < x; i++)
    {
        arr2[i] = i;
        printf("Array at %d is %d.\n", i, arr2[i]);
    }
    return 0;
}

Этот код C компилируется и запускается без каких-либо проблем — никаких ошибок сегмента или чего-то еще. В чем дело? Является ли этот код допустимым C, и я только что изучил его в IDE, которая не позволяла это, или это недопустимый код C, и я просто использую плохой компилятор? На другом моем компьютере с Linux я даже установил GCC 7.2, и разрешен тот же синтаксис. Я не понимаю. Это проблема CLion, проблема CMake или проблема C lang?

Мой компилятор и CMake перечислены ниже. Спасибо.

введите здесь описание изображения


person Hatefiend    schedule 23.09.2017    source источник
comment
@chris Хотя я ценю возможное решение, не могли бы вы объяснить его контекст? Что это такое, зачем его использовать и т.   -  person Hatefiend    schedule 23.09.2017
comment
Плохо, мой мозг был в режиме C++, где ошибочное использование VLA действительно распространено. Флаг для предупреждения об использовании расширений.   -  person chris    schedule 23.09.2017
comment
Вы упустили одну возможность: язык изменился, когда вы не смотрели! Когда-то вы были правы, размеры массивов должны были быть постоянными, но в более новых версиях стандарта C, поддерживаемых более новыми компиляторами, есть VLA (массивы переменной длины), где размер может быть переменной.   -  person Steve Summit    schedule 23.09.2017
comment
Если 18 лет считается более новым стандартом! Это вечность в вычислениях   -  person M.M    schedule 23.09.2017


Ответы (1)


Это допустимый C. Он называется массивом переменной длины (VLA). Эта функция была добавлена ​​в язык как часть стандарта C99.

MSVC хорошо известен тем, что не поддерживает многие функции C99 и более поздних версий, включая VLA.

person dbush    schedule 23.09.2017
comment
Спасибо за информацию. Итак, у меня есть последний вопрос: в какой среде я должен кодировать C? Возможность кодировать таким образом, безусловно, снимает большую нагрузку с необходимости создавать буферы определенного размера, угадывать и надеяться, что он будет достаточно большим для пользовательского ввода и т. д. С VLA мне не нужно беспокоиться об этом. много. Должен ли я кодировать в стандарте C99, странной штуке Microsoft C99 или C11? Принимает ли сообщество программистов C VLA или хардкорные программисты C думают, что это противоречит пути языка. К вашему сведению, я всего лишь студент колледжа. - person Hatefiend; 23.09.2017
comment
@Hatefiend Если вы используете компилятор, который его поддерживает, и вам не нужно беспокоиться о работе в MSVC, используйте его. Альтернативой является динамическое выделение памяти с помощью malloc и free. - person dbush; 23.09.2017
comment
Не волнуйтесь, я использовал malloc и free тонну для подобных ситуаций. Я думал, что это одна из основных характеристик языка Си. С VLA C неожиданно стал больше напоминать мне Java. Вот почему я спрашиваю, какая самая популярная версия стандарта C для программистов на C. - person Hatefiend; 23.09.2017
comment
@Hatefiend Если верить свидетельствам здесь, на SO, все используют C99 или более позднюю версию. Такие функции, как VLA, не новы и не отличаются; теперь они являются обычной частью языка. (Вверху вы можете видеть, как кто-то дразнит меня — и вполне оправданно — за то, что я говорю, что они являются частью более новых версий стандарта C.) - person Steve Summit; 23.09.2017