Ответ 1
В большинстве случаев (по крайней мере на C) вы обнаружите, что sizeof(*x)
вообще не оценивает *x
. Стандарт C99 имеет это, например, в 6.5.3.4 The sizeof operator
, part /2
(my bolding):
Оператор sizeof дает размер (в байтах) своего операнда, который может быть выражением или заключенным в скобки именем типа. Размер определяется из типа операнда. Результат - целое число. Если тип операнда - тип массива переменной длины, то операнд оценивается; в противном случае операнд не оценивается, а результат представляет собой целочисленную константу.
Итак, для всех не-VLA разыменование не происходит. Если тип *x
является VLA, который рассмотрел фазу исполнения sizeof
, то, что нужно проработать во время работы кода, - все остальные могут быть вычислены во время компиляции.
С++ имеет несколько разные правила, как показано в 5.3.3. Sizeof
, part /1
:
Оператор sizeof дает количество байтов в представлении объекта своего операнда. Операндом является либо выражение, которое является неоцененным операндом (раздел 5), либо идентификатором типа в скобках.
5. Expressions
определяет термин "неоцененный операнд" в части /8
:
В некоторых контекстах отображаются неоцененные операнды. Неопределенный операнд не оценивается.
(возможно, одна из самых бесполезных избыточных фраз, которые я читал на некоторое время, но я не знаю, что происходит с сознанием людей ИСО, когда они написали ее).