Поведение sizeof для массивов переменной длины (только C)

Мой вопрос в том, как именно sizeof() ведет себя, когда переданный аргумент представляет собой массив переменной длины .

Рассмотрим пример:

int fun(int num_of_chars)
{
    char name_arr[num_of_chars] = {0};

    /* Do something*/

    return sizeof(name_arr);
}

В этом примере очевидно, что возвращаемое значение не является постоянной времени компиляции. Поскольку размер зависит от значения времени выполнения num_of_chars.

Цитата из стандарта C99 (6.5.3.4):

Оператор sizeof дает размер (в байтах) своего операнда, который может быть     выражение или имя в скобках типа. Размер определяется из     тип операнда. Результат - целое число. Если тип операнда является     тип массива переменной длины, операнд оценивается; в противном случае операнд     не оценивается, а результат представляет собой целочисленную константу.

То, что я могу понять из [.... операнда оценивается....], заключается в том, что когда аргумент, переданный для sizeof(), представляет собой массив переменной длины динамического массива, sizeof() 'ведет себя как функция, а не как оператор.

Насколько я понимаю?

Ответ 1

Он по-прежнему ведет себя как оператор. Cast также является оператором, а также оценивает его аргумент, а также * или &. Быть оператором является синтаксической категорией. Это не меняется.

Важным отличием является то, что он ведет себя как выражение, а в других случаях он ведет себя как константа.


Обновление: я прокомментировал ниже, что я не понимаю, почему оценка имеет значение, но теперь я понял, что вы можете написать sizeof с массивом переменной длины. Либо вы можете передать переменную, объявленную как переменный длинный массив:

int a[x];
sizeof(a)

и в этом случае оценка a действительно не имеет значения. Но вы также можете использовать тип в качестве аргумента, который был бы

sizeof(int[x])

и в этом случае результат x * sizeof(int) и x должен быть оценен. Полагаю, именно поэтому спецификация упоминает его.

Ответ 2

Мой вопрос в том, как именно ведет себя sizeof(), когда переданный аргумент является динамическим массивом.

  • Ну, вы скорее означали "массив переменной длины" (VLA).

  • Он ведет себя почти точно: он возвращает размер массива в байтах.

sizeof() 'ведет себя как функция, а не как оператор.

Нет, это никогда не было функцией. Единственное, что меняется, это то, что если он используется в VLA, этот оператор не дает константы времени компиляции, в противном случае это делает.