28 votes

sizeof avec un type ou une variable

J'ai récemment vu quelqu'un féliciter un autre utilisateur pour son utilisation de sizeof var au lieu de sizeof(type). J'ai toujours pensé que c'était juste un choix de style. Y a-t-il une différence significative ? A titre d'exemple, les lignes avec f et ff ont été considérées comme meilleures que les lignes avec g et gg :

 typedef struct _foo {} foo;

 foo *f = malloc(count * sizeof f);
 foo *g = malloc(sizeof(foo) * count);

 foo **ff = malloc(count * sizeof *ff);
 foo **gg = malloc(sizeof(foo*) * count);

À mon avis, la première série est juste une question de style. Mais dans la deuxième paire de lignes, le deuxième * supplémentaire peut facilement être confondu avec une multiplication.

53voto

Steve Fallows Points 4059

Si le type de la variable est modifié, il ne sera pas nécessaire de changer la taille de la variable si celle-ci est l'argument, plutôt que le type.

Concernant le commentaire de @icepack : la possibilité ou la probabilité de changement du type par rapport au nom de la variable n'est pas le problème. Imaginez que le nom de la variable soit utilisé comme argument de sizeof et qu'il soit ensuite modifié. Dans le meilleur des cas, une opération de refactor-rename modifie toutes les occurrences et aucune erreur n'est introduite. Dans le pire des cas, une instance de sizeof est manquée et le compilateur se plaint et vous devez la corriger. Si le type est modifié, c'est terminé, il n'y a pas de possibilité d'erreur dans les instructions sizeof.

Maintenant, imaginez que le type est l'argument de sizeof. Si le type de la variable est modifié, il n'y a aucun autre moyen que l'inspection pour trouver tous les sizeof relatifs à cette variable. Vous pouvez effectuer une recherche, mais vous obtiendrez des résultats pour toutes les utilisations non liées de sizeof du même type. Si l'une d'entre elles est manquée, vous aurez un problème d'exécution dû à une inadéquation de taille, ce qui est beaucoup plus difficile à trouver.

8voto

En plus de ce que Steve dit, laissez-moi ajouter que sizeof n'évalue pas son opérande. Vous êtes donc libre d'y faire ce que vous voulez. Non seulement vous pouvez utiliser des variables non encore initialisées, mais vous pouvez déréférencer un pointeur nul, appeler des fonctions non définies mais seulement déclarées et faire tout autre type de choses. Je vous encourage à toujours utiliser la version expression pour les raisons que Steve a largement expliquées.

Il faut également tenir compte du fait que les noms de types sont parfois très longs et illisibles. Il suffit de penser aux pointeurs vers les fonctions (notamment en C++). Au lieu d'écrire sizeof(my_long_type<weird, stuff>) tu fais juste sizeof t .

4voto

caf Points 114951

Vous ne verrez peut-être que peu de différence entre eux :

foo **ff = malloc(count * sizeof *ff);
foo **gg = malloc(sizeof(foo*) * count);

mais que faire si l'allocation n'est pas proche de la déclaration ? Si je tombe sur une ligne comme :

ff = realloc(ff, count * sizeof *ff);

alors je suis raisonnablement sûr que la ligne est correcte, sans même me souvenir du type de ff . Cependant, si je vois ceci :

ff = realloc(ff, count * sizeof(foo *));

alors je pourrais être un peu suspicieux, et avoir besoin de chercher le type de ff pour mettre mon esprit au repos.

3voto

Martin v. Löwis Points 61768

Les lignes f et ff sont définitivement pires que g et gg. sizeof f est la taille du pointeur, puisque f est un point. Pour les rendre équivalents, il faudrait écrire sizeof *f (ou, pour une meilleure lisibilité, sizeof(*f) ).

2voto

Jonathan Leffler Points 299946

J'ai tendance à utiliser sizeof(type) dans l'allocation de la mémoire, mais invariablement sizeof(variable) lors de l'utilisation d'une variable locale ou globale. Néanmoins, il y a de la sagesse dans le conseil d'utiliser le nom de la variable tout le temps.

J'ai également eu une longue discussion (assez animée par moments, et qui a duré plusieurs jours - nous avons fini par accepter de ne pas être d'accord sur la question) sur la question de savoir s'il est correct d'utiliser sizeof(variable) ou si elle doit être sizeof variable c'est-à-dire qu'il est important de savoir si les parenthèses entourent l'argument de l'option sizeof . Je n'ai jamais rencontré un compilateur qui s'agite autour de sizeof(variable) j'opte donc pour l'uniformité et utilise toujours les parenthèses avec sizeof . Mon collègue était tout aussi catégorique sur le fait que les parenthèses ne doivent pas être utilisées avec les variables ; que d'une manière ou d'une autre, il y a/avait une distinction précieuse entre la notation avec et sans les parenthèses. Je n'ai pas été convaincu et je ne m'attends pas à l'être.

Dans un tout autre ordre d'idée, quelques autres points concernant sizeof :

  • Si vous utilisez C99 et VLA (réseaux à longueur variable), alors sizeof(vla) n'est pas une constante de temps de compilation. Attention !
  • Le pré-processeur C ne comprend pas sizeof ce qui est gênant mais logique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X