c - length - sizeof си массив




Почему sizeof(x++) не увеличивает x? (6)

Вот код, скомпилированный в dev c ++ windows:

#include <stdio.h>

int main() {
    int x = 5;
    printf("%d and ", sizeof(x++)); // note 1
    printf("%d\n", x); // note 2
    return 0;
}

Я ожидаю, что x будет 6 после выполнения примечания 1 . Однако выход:

4 and 5

Может ли кто-нибудь объяснить, почему x не увеличивается после примечания 1 ?


Выполнение не может произойти во время компиляции. Так что ++i / i++ не произойдет. Также sizeof(foo()) не выполняет функцию, а возвращает правильный тип.


Из стандарта C99 (акцент мой)

6.5.3.4/2

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


Заметка

Этот ответ был объединен из дубликата, что объясняет позднюю дату.

оригинал

За исключением массивов переменной длины sizeof не оценивает свои аргументы. Мы можем видеть это из проекта стандартного раздела C99 6.5.3.4 Оператор sizeof оператора, который гласит:

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

Комментарий ( теперь удаленный ) спросил, будет ли что-то подобное оцениваться во время выполнения:

sizeof( char[x++]  ) ;

и действительно, было бы так, что-то вроде этого тоже будет работать ( см. их обоих ):

sizeof( char[func()]  ) ;

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

Примечание. Массивы переменной длины описаны в стандартном разделе проекта C99. 6.7.5.2 Объявление декларатора массива, пункт 4 :

[...] Если размер представляет собой целочисленное константное выражение, а тип элемента имеет известный постоянный размер, тип массива не является массивом переменной длины; в противном случае тип массива представляет собой тип массива переменной длины.

Обновить

В C11 ответ изменяется для случая VLA, в некоторых случаях неопределено, оценивается ли выражение размера или нет. Из раздела 6.7.6.2 массива, которые гласят:

[...] Если выражение размера является частью операнда оператора sizeof и изменение значения выражения размера не повлияет на результат оператора, то не определено, оценивается ли выражение размера.

Например, в таком случае ( см. Его в прямом эфире ):

sizeof( int (*)[x++] )

sizeof() дает размер только типа данных, он не оценивает внутренние элементы.


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

short func(short x) {  // this function never gets called !!
   printf("%d", x);    // this print never happens
   return x;
}

int main() {
   printf("%d", sizeof(func(3))); // all that matters to sizeof is the 
                                  // return type of the function.
   return 0;
}

Выход:

2

так как short занимает 2 байта на моей машине.

Изменение возвращаемого типа функции в double :

double func(short x) {
// rest all same

даст 8 качестве вывода.


sizeof является встроенным оператором компиляции и не является функцией. Это становится очень ясным в тех случаях, когда вы можете использовать его без круглых скобок:

(sizeof x)  //this also works






sizeof