O que faz o sizeof sem ()?

O autor desta pergunta apenas zombou de mim quando perguntei a ele o sizeof * q faz … Ele me disse que essa é uma pergunta básica sobre C e eu deveria dar uma olhada. Mas como eu olhei ao redor em SO e não vi alguém perguntando antes, eu vou fazer agora por mim mesmo:

O que faz o sizeof em C quando é usado sem parênteses e / ou tipo?

Então, se olharmos para a gramática do sizeof da seção padrão do projeto C99 6.5.3 , o parágrafo 1 dos operadores unários é o seguinte:

 sizeof unary-expression sizeof ( type-name ) 

Há uma diferença que você não pode usar um nome de tipo sem os parênteses e a seção 6.5.3.4 O 6.5.3.4 operador, parágrafo 2, diz ( ênfase minha ):

O operador sizeof produz o tamanho (em bytes) de seu operando, que pode ser uma expressão ou o nome entre parênteses de um tipo .

Para completar você pode se perguntar se podemos usar sizeof com uma expressão se tivermos parenthesizes e a resposta for sim, uma vez que uma expressão unária pode conter parenthesizes. A maneira mais fácil de ver isso seria procurar na seção A.2.1 Expressões do padrão de rascunho e trabalhar com a gramática da seguinte forma:

 unary-expression -> postfix-expression -> primary-expression -> ( expression ) 

sizeof é um operador, não uma function, então você não precisa do () se o operando for uma expressão (mas você normalmente os usa). sizeof * q == sizeof(*q) . Note que se o operando é um tipo, você precisa usar o () , então sizeof(int) (veja por exemplo http://en.wikibooks.org/wiki/C_Programming/Reference_Tables )

 sizeof sizeof operator for expressions sizeof 123 sizeof() sizeof operator for types sizeof (int) 

Agora até o wiki está cheio de informações sobre C … O mundo está mudando rapidamente 🙂

O operador sizeof é usado para determinar a quantidade de espaço que um tipo de dados designado ocuparia na memory. Para usar sizeof, a palavra-chave “sizeof” é seguida por um nome de tipo ou uma expressão (que pode ser meramente um nome de variável). Se um nome de tipo for usado, ele deve sempre ser colocado entre parênteses, enquanto expressões podem ser especificadas com ou sem parênteses.

sizeof é um operador , especificamente um operador unário como unary & ou ++ . É necessária uma expressão unária ou um nome de tipo cercado por parens como seu operando.

A syntax é

   tamanho da expressão unária 
   sizeof ( nome do tipo )

Então, dada uma declaração como

 int *q; 

as expressões sizeof *q e sizeof (int) são equivalentes, assim como sizeof q e sizeof (int *) .

A mesma coisa que sizeof com parantheses. É um operador unário do lado direito, por isso trata o tamanho certo como operando.
Tanto quanto eu sei paranthesis são obrigatórios ao usar sizeof com tipos de dados básicos.

Quando você tem uma variável int a você pode verificar seu tamanho nos dois sentidos, parênteses não são obrigatórios: sizeof a , sizeof (a) funcionará da mesma forma.
Mas ao verificar o tamanho do int em si só sizeof (int) funcionará.

A mesma coisa que faz com parens – ele retorna o tamanho de qualquer coisa que você passe, neste caso o tamanho do que quer que seja apontado por q .

É um pouco menos claro, especialmente quando nos envolvemos com chamadas complexas para malloc e sizeof , então eu considero ser a melhor prática sempre usar os parênteses.