Массив переменной длины с длиной 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

Другие вопросы по тегам