Que fait sizeof without ()?

L’auteur de cette question vient de se moquer de moi lorsque je lui ai demandé quelle sizeof * q … Il m’a dit que c’était une question C très basique et que je devrais y jeter un coup d’œil. Mais comme j’ai regardé SO et que je n’ai encore jamais vu quelqu’un demander, je vais le faire moi-même:

Que fait sizeof en C quand il est utilisé sans parenthèses et / ou sans type?

Donc, si nous examinons la grammaire de sizeof dans le paragraphe 1 du projet de norme standard C99, Opérateurs 6.5.3 lit comme suit:

 sizeof unary-expression sizeof ( type-name ) 

Il y a une différence que vous ne pouvez pas utiliser un nom de type sans parenthèses et la section 6.5.3.4 L’opérateur sizeof, paragraphe 2, dit ( souligné par moi ):

L’opérateur sizeof donne la taille (en octets) de son opérande, qui peut être une expression ou le nom entre parenthèses d’un type . […]

Par souci d’exhaustivité, vous pouvez vous demander si nous pouvons utiliser sizeof avec une expression si nous avons des parenthèses et que la réponse est oui, car une expression unaire peut elle même contenir des parenthèses. La meilleure façon de voir cela consiste à consulter la section A.2.1 Expressions du projet de norme et à travailler avec la grammaire de la manière suivante:

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

sizeof est un opérateur, pas une fonction, vous n’avez donc pas besoin de () si l’opérande est une expression (mais vous les utilisez normalement). sizeof * q == sizeof(*q) . Notez que si l’opérande est un type, vous devez utiliser le () , donc sizeof(int) (voir par exemple http://en.wikibooks.org/wiki/C_Programming/Reference_Tables )

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

Maintenant, même le wiki regorge d’informations sur C … Le monde change rapidement 🙂

L’opérateur sizeof est utilisé pour déterminer la quantité d’espace qu’un type de données désigné occuperait en mémoire. Pour utiliser sizeof, le mot clé “sizeof” est suivi d’un nom de type ou d’une expression (qui peut être simplement un nom de variable). Si un nom de type est utilisé, il doit toujours être placé entre parenthèses, tandis que les expressions peuvent être spécifiées avec ou sans parenthèses.

sizeof est un opérateur , en particulier un opérateur unaire tel que unary & ou ++ . Il prend soit une expression unaire, soit un nom de type entouré d’opérandes.

La syntaxe est

   taille d'une expression unaire 
   sizeof ( nom du type )

Donc, étant donné une déclaration comme

 int *q; 

les expressions sizeof *q et sizeof (int) sont équivalentes, de même que sizeof q et sizeof (int *) .

La même chose que sizeof avec des parenthèses. C’est un opérateur unaire du côté droit, il traite donc sa taille correcte comme un opérande.
Pour autant que je sache, les parenthèses sont obligatoires pour l’utilisation de sizeof avec des types de données de base.

Lorsque vous avez une variable int a vous pouvez vérifier sa taille dans les deux sens, les parenthèses ne sont pas obligatoires: sizeof a , sizeof (a) fonctionnera de la même manière.
Mais lors de la vérification de la taille de int, seul sizeof (int) fonctionnera.

La même chose que fait avec parens – il retourne la taille de ce que vous passez, dans ce cas, la taille de tout ce qui est indiqué par q .

Cependant, c’est un peu moins clair, surtout quand nous sums impliqués dans des appels complexes à malloc et à sizeof . Je considère donc qu’il est préférable de toujours utiliser les parens.