Почему sizeof int неверен, а sizeof (int) прав?

Мы знаем, что sizeof - это оператор, используемый для вычисления размера любого типа данных и выражения, а когда операнд является выражением, круглые скобки могут быть опущены.

int main()
{
        int a;

        sizeof int;
        sizeof( int );
        sizeof a;
        sizeof( a );

        return 0;
}

первое использование sizeof неверно, в то время как другие правы.

Когда он скомпилирован с использованием gcc, будет указано следующее сообщение об ошибке:

main.c:5:9: error: expected expression before ‘int’

Мой вопрос в том, почему стандарт C не допускает такого рода операции. Будет ли sizeof int вызывать какую-либо двусмысленность?

Ответ 1

Следующие могут быть неоднозначными:

sizeof int * + 1

Это (sizeof (int*)) + 1, или (sizeof(int)) * (+1)?

Очевидно, язык C мог ввести правило для устранения двусмысленности, но я могу себе представить, почему это не беспокоило. С языком в его нынешнем виде спецификатор типа никогда не появляется "голым" в выражении, и поэтому нет необходимости в правилах для разрешения того, является ли эта вторая * частью типа или арифметического оператора.

Существующая грамматика уже разрешает потенциальную двусмысленность sizeof (int *) + 1. Это (sizeof(int*))+1, а не sizeof((int*)(+1)).

С++ имеет несколько схожую проблему, чтобы решить синтаксис синтаксиса в стиле функции. Вы можете написать int(0), и вы можете написать typedef int *intptr; intptr(0);, но вы не можете написать int*(0). В этом случае разрешение заключается в том, что тип "голый" должен быть простым именем типа, он не может быть просто старым идентификатором типа, в котором могут быть пробелы, или препинанием пунктуации. Возможно, sizeof мог быть определен с тем же ограничением, я не уверен.

Ответ 2

От Стандарт C99

6.5.3.4.2
Оператор sizeof дает размер (в байтах) своего операнда, который может быть выражением или заключенным в скобки именем тип.

В вашем случае int не является ни выражением, ни заключенным в скобки именем.

Ответ 3

Существует два способа использования оператора sizeof в C. Синтаксис таков:

C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )

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

Стандарт C дает один такой пример того, где вы можете использовать его в выражении:

sizeof array / sizeof array[0]

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