Вот код, скомпилированный в 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 ?
VLAs
ни один из остальных не делает.Ответы:
Из стандарта C99 (акцент мой)
источник
N
из stdin и делаете makeint array[N]
. Это одна из функций C99, недоступная в C ++.sizeof(int[++x])
(действительно, действительно плохая идея, во всяком случае)++
можно было бы оценить.gcc
,clang
и в ideone.com/Pf7iFsizeof
является оператором времени компиляции, поэтому во время компиляцииsizeof
его операнд заменяется значением результата. Операнд не вычисляется (кроме случаев , когда это переменная массива длины) на всех; имеет значение только тип результата.Вывод:
как
short
занимает 2 байта на моей машине.Изменение типа возвращаемого значения функции
double
:даст в
8
качестве вывода.источник
sizeof(foo)
очень старается определить размер выражения во время компиляции:6.5.3.4:
Вкратце: массивы переменной длины, запускаемые во время выполнения. (Примечание. Массивы переменной длины - это особая функция, а не массивы, выделенные с помощью
malloc(3)
.) В противном случае вычисляется только тип выражения и тот, который используется во время компиляции.источник
sizeof
является встроенным оператором времени компиляции и не является функцией. Это становится очень понятным в тех случаях, когда вы можете использовать его без скобок:источник
sizeof
Оператор не оператор времени компиляции, вам нужно только дать ему VLA , чтобы понять это.Запись
Этот ответ был объединен с дубликатом, который объясняет позднюю дату.
оригинал
За исключением массивов переменной длины sizeof не оценивает его аргументы. Мы можем видеть это из стандартного раздела проекта C99
6.5.3.4
Оператор SizeOf пункта 2 , который гласит:Комментарий ( теперь удаленный ) спросил, будет ли что-то подобное оцениваться во время выполнения:
и действительно, что-то подобное будет работать ( смотрите их вживую ):
так как они оба массивы переменной длины. Хотя я не вижу большого практического использования ни в одном из них.
Обратите внимание, что массивы переменной длины описаны в черновом варианте стандартного раздела C99, описанном в разделе
6.7.5.2
4 :Обновить
В C11 ответ изменяется для случая VLA, в некоторых случаях не определено, оценивается ли выражение размера или нет. Из раздела
6.7.6.2
Array объявлений, в котором говорится:Например, в случае, как это ( см. Это в прямом эфире ):
источник
sizeof
по сути, макрос - он не создает код, а предварительно вычисляет ожидаемое значение и вносит его прямо в код. Обратите внимание, что это было единственное поведение до C99, поскольку VBA не существовало (я никогда не слышал о них до этого ответа, верьте этому или нет!)sizeof (char[x++]);
использоваться значениеx
для чего-либо, кроме определения значения выраженияx++
и нового значения дляx
, оба из которых являются нормальными для этого оператора?char[x++]
что это VLA это выглядит эффективно, какchar*
мои незнакомые глаза.Поскольку операнд
sizeof
оператора не оценивается, вы можете сделать это:Демо онлайн: http://ideone.com/S8e2Y
То есть вам не нужно определять функцию,
f
если она используетсяsizeof
только в. Эта техника в основном используется в метапрограммировании шаблонов C ++, поскольку даже в C ++ операндsizeof
не оценивается.Почему это работает? Это работает, потому что
sizeof
оператор не оперирует значением , а работает с типом выражения. Поэтому, когда вы пишетеsizeof(f())
, он работает с типом выраженияf()
, и это не что иное, как тип возврата функцииf
. Тип возвращаемого значения всегда один и тот же, независимо от того, какое значение возвращает функция, если она действительно выполняется.В C ++ вы можете даже это:
Тем не менее, похоже,
sizeof
что сначала я создаю экземплярA
, пишуA()
, а затем вызываю функциюf
экземпляра, пишуA().f()
, но ничего подобного не происходит.Демо: http://ideone.com/egPMi
Вот еще одна тема, которая объясняет некоторые другие интересные свойства
sizeof
:источник
Выполнение не может произойти во время компиляции. Так
++i
/i++
не случится. Такжеsizeof(foo())
не будет выполнять функцию, но вернет правильный тип.источник
sizeof
выражение постоянной времени компиляции»?sizeof
выполняется во время компиляции, ноx++
может оцениваться только во время выполнения. Чтобы решить эту проблему, стандарт C ++ диктует, что операндsizeof
не оценивается. Стандарт C говорит:источник
sizeof()
Оператор задает только размер типа данных, он не оценивает внутренние элементы.источник
sizeof()
оператор действует рекурсивно и получает размер в байтах всех элементов контейнера, членов класса или структуры и т. Д. Вы можете легко доказать это сами, создав простой класс с несколькими членами и зовуsizeof()
на это. (Тем не менее, все, что там является указателем, не может видеть размер - только размер указателя.) Это происходит все во время компиляции, как заявили другие комментаторы: выражения внутриsizeof()
не оцениваются.