¿Por qué (y cuándo) necesito usar paréntesis después de sizeof?

El siguiente no puede comstackr:

typedef int arr[10]; int main(void) { return sizeof arr; } sizeof.c:3: error: expected expression before 'arr' 

pero si lo cambio a

 sizeof(arr); 

todo esta bien. ¿Por qué?

De acuerdo con 6.5.3, hay dos formas para sizeof como las siguientes:

 sizeof unary-expression sizeof ( type-name ) 

Como el código es un type-name , tiene que estar entre paréntesis.

Esa es la forma en que se especifica el idioma, los nombres de tipos deben estar entre paréntesis aquí.

Supongamos que la gramática se veía así:

sizeof unary-expression sizeof type-name

Ahora, por ejemplo, la siguiente expresión sería ambigua:

 sizeof int * + 0 

Podría ser sizeof(int *) + 0 o sizeof(int) * +0 . Esta ambigüedad no se presenta para expresiones unarias, ya que un asterisco agregado a una expresión no es una expresión (pero para algunos nombres de tipos, al agregar uno, nuevamente se encuentra un nombre de tipo).

Algo tenía que especificarse aquí y exigir que los nombres de tipos que se entre paréntesis es una forma de resolver la ambigüedad.

Creo que es porque tienes typedef . Si lo eliminas, debería comstackrse.

Ejemplo de wikipedia:

 /* the following code fragment illustrates the use of sizeof * with variables and expressions (no parentheses needed), * and with type names (parentheses needed) */ char c; printf("%zu,%zu\n", sizeof c, sizeof (int));