Подтвердить что ты не робот

Является ли 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() ) юридическим выражением?", особенно подробно о том, как соответствие грамматики работает, когда совпадают оба вышеуказанных маркированных случая.

4b9b3361

Ответ 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)