Массив переменной длины с длиной 0?
В C массиву обычно не разрешается иметь размер 0 (если я не использую одно или другое расширение на стороне компилятора).
OTOH, есть VLA, длина которых может оказаться равной 0.
Они разрешены?
Я говорю о следующем коде:
void send_stuff()
{
char data[4 * !!flag1 + 2 * !!flag2];
uint8_t cursor = 0;
if (flag1) {
// fill 4 bytes of data into &data[cursor]
cursor += 4;
}
if (flag2) {
// fill 2 bytes of data into &data[cursor]
cursor += 2;
}
}
Результатом является data
массив длиной 0, 2, 4 или 6, в зависимости от комбинации флагов.
Вопрос теперь: является ли этот допустимый код для случая, когда массив оказывается длиной 0?
1 ответ
Это недействительно, если мы перейдем к черновому стандартному разделу C99 6.7.5.2
Массив деклараторов в пункте 5 гласит (выделено мое):
если размер является выражением, которое не является целочисленным константным выражением: если оно встречается в объявлении в области действия прототипа функции, оно обрабатывается так, как если бы оно было заменено *; в противном случае каждый раз, когда он оценивается, он должен иметь значение больше нуля.[...]
На самом деле с clang
включение дезинфицирующего средства для неопределенного поведения с помощью -fsanitize=undefined
Флаг может генерировать предупреждение во время выполнения для этого случая, смотрите его вживую:
ошибка времени выполнения: привязка массива переменной длины к неположительному значению 0