Является ли sizeof (int()) законным выражением?
Этот вопрос вдохновлен Является ли sizeof (void()) юридическим выражением?, но имеет важное различие, как описано ниже.
Соответствующее выражение:
sizeof( int() )
В грамматике С++ появляется:
Унарный-выражение:
-
sizeof
унарное выражение -
sizeof (
type-id )
однако ( int() )
может соответствовать обоим этим случаям с разными значениями:
- Как унитарное выражение, это инициализированное значение
int
prvalue, окруженное резервными скобками
- В качестве идентификатора типа это тип функции без параметров, возвращающих
int
.
В семантических ограничениях для sizeof
, то есть С++ 14 [expr.sizeof]/1, объясняется, что форма sizeof(
type-id )
не может применяться к типу функции.
Однако я не уверен, что нарушение этого семантического ограничения означает, что sizeof( int() )
является правильным и использует форму унарного выражения sizeof
; или существует ли какое-то другое правило, которое устраняет неоднозначность этих двух случаев на более ранней стадии согласования грамматики.
NB. По другому вопросу sizeof(void())
, ни одна интерпретация не является допустимой, поэтому можно утверждать, что компилятор правильно отклоняет выражение с сообщением об ошибке, указывающим, что он соответствует форме идентификатора типа. Однако gcc отклоняет sizeof( int() )
сообщение о типе-идентификаторе.
Чтобы быть ясным, мой вопрос: "Является ли sizeof( int() )
юридическим выражением?", особенно подробно о том, как соответствие грамматики работает, когда совпадают оба вышеуказанных маркированных случая.
Ответы
Ответ 1
Нет, sizeof( int() )
плохо сформирован, потому что int()
считается идентификатором типа. В частности, это тип функции, а sizeof
не может применяться к типу функции.
[dcl.ambig.res]/2:
Неоднозначность может возникать из-за сходства между функциональным стилем cast и идентификатор типа. Резолюция такова, что любая конструкция, которая могла бы возможно, является идентификатором типа в его синтаксическом контексте, считается тип-идентификатор.
с данным точным примером:
void foo(signed char a) {
sizeof(int()); // type-id (ill-formed)
sizeof(int(a)); // expression
sizeof(int(unsigned(a))); // type-id (ill-formed)