Создание фиксированного массива - какого чёрта оно работает?

Добрый день, камрады

Столкнулся с непонятным (для меня) поведением при создании фиксированного массива:

  if (dWin.available()) {
    delay(2);
    uint8_t size = dWin.available();
    uint8_t buffer[size]{};
    dWin.readBytes(buffer, size);
    Serial.print(size);
    Serial.print(": ");
    printBuf(buffer, size);
}

Почему массив создается (а он создается, глюков каких-то поймать не смог пока), компилятор не ругается, хотя его размер на момент компиляции не известен?

Потому что так работает язык?

А что вы имеете в виду под понятием “фиксированного массива” ?

Курю букварь и там:

Поскольку массивам фиксированного размера память выделяется во время компиляции, то здесь мы имеем два ограничения:

  1. Массивы фиксированного размера не могут иметь длину, основанную на любом пользовательском вводе или другом значении, которое вычисляется во время выполнения программы (runtime).

  2. Фиксированные массивы имеют фиксированную длину, которую нельзя изменить.

Фиксированного размера, сорри за неточность

что за букварь? Он точно по Си ?

Можно подумать в С есть какие-то другие массивы, размер которых можно менять…

Дерьмовый букварь, не кури такой больше.

Широко известный в узких кругах :))) Уроки С++ для начинающих / Ravesli

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

Правило создания массива такое - размер массива должен быть известен к моменту его создания.

Ок, почему тогда этот пример в VS не компилируется?

	uint8_t size;
	cin >> size;
	uint8_t buffer[size]{};

|Ошибка (активно)|E0028|выражение должно иметь константное значение переменная size (объявлено в строке 164) невозможно использовать как константу.

Может потому, что это не правильно?

Потому что VS совместима только с древним стандартом C90

да и не должен…

Что-то я запутался, пожалуй постою в сторонке, послушаю что другие скажут.

Перефразирую вопрос. Создаю массив в ардуино IDE:

uint8_t size = dWin.available();
uint8_t buffer[size]{};

и в VS:

uint8_t size;
cin >> size;
uint8_t buffer[size]{};

На мой взгляд они идентичны - размер массива задается в ходе выполнения программы, во время компиляции он неизвестен. Однако первый пример компилируется и работает (для меня неожиданно), а второй не компилируется с ошибкой выражение должно иметь константное значение переменная size (объявлено в строке 1) невозможно использовать как константу (для меня ожидаемо). Почему так происходит. Уважаемый rkit упомянул про изменение стандартов, возможно он сможет ткнуть носом где почитать про изменения в этом вопросе?

обсасывали же уже…
https://forum.arduino.ru/t/mne-tolko-sprosit/10185/98?u=xdriver

Ошибка. Эта страница не существует или скрыта от публичного просмотра.

да, там для “избранных”))

А можно для простолюдов?

Пересылаю от Петровича:

Вообще-то нельзя (хотя, я не помню, как в стандарте 2020, сейчас гляну). Все стандарты до 2017 включительно, требовали там константу или константное выражение.

Но в GCC - пожалуйста. Это документированное расширение языка, поддерживаемое GCC.

Update:
Посмотрел в 2020, всё также - обязательно константное выражение:

1 лайк

Спасибо мил-человек, а то я битых три часа на это диво-дивное смотрел и поломать пытался, а оно никак ломаться не хочет.