J'ai vu deux styles d'utilisation sizeof
pour les opérations liées à la mémoire (comme dans memset
ou malloc
):
sizeof(type)
, etsizeof variable
ousizeof(variable)
Lequel préféreriez-vous, ou utiliseriez-vous un mélange des deux styles, et quand utiliseriez-vous chaque style? Quels sont les avantages et les inconvénients de chaque style et quand les utilisez-vous?
À titre d'exemple, je peux voir la paire de situations suivante où un style aide et l'autre non:
Lorsque vous obtenez l'indirection du pointeur incorrecte:
type *var;
...
memset(var, 0, sizeof var); /* oops */
Lorsque le type change:
new_type var; /* changed from old_type to new_type */
...
memset(&var, 0, sizeof(old_type)); /* oops */
la source
array
s'agit bien d'un tableau C, puissizeof(array)
retourne le nombre d'octets requis pour stocker les éléments du tableau . Siarray
est un pointeur sur le premier élément d'un tableau C pourri, alors votre instruction est vraie. Passer un tableau C comme argument de fonction le fait ressembler à un pointeur dans la fonction - toutes les informations prouvant qu'il s'agissait d'un tableau, comme sa taille, sont perdues. Voilà pourquoi il est pourri . Faux 2: "les tableaux n'existent pas réellement en C; ... simplement du sucre syntaxique pour les pointeurs."La préférence (comme toujours) est de refléter votre intention aussi directement que possible.
L'intention est-elle d'opérer contre la mémoire d'une variable existante? Si c'est le cas, alors utilisez
sizeof(variable)
, car cela montre le plus fidèlement possible que c'est la mémoire de la variable elle-même qui vous intéresse.L'intention est-elle d'effectuer un calcul sur le type, par exemple pour déterminer la quantité de mémoire à allouer pour une nouvelle instance? Si oui, utilisez
sizeof(type)
.Autrement dit, je préfère
plus de
comme ce dernier cas ressemble que vous essayez d'accéder à une variable qui n'existe pas, encore.
Par contre, je préfère
plus de
comme l'intention est clairement de remplir à zéro le contenu de la variable, c'est donc la variable contre laquelle nous devons opérer. Essayer d'utiliser le type de métadonnées confond simplement les choses, ici.
la source
void *
les fichiers sont automatiquement transtypés vers d'autres types de pointeurs comme une erreur.Je préférerais largement
sizeof(type)
plussizeof variable
. Même si elle vous oblige à vous soucier plus sur le type et faire plus de changements, il vous aide à éviter les erreurs d'indirection de pointeur, qui se classent parmi les cause de bogues dans C .Je ne m'inquiéterais pas autant des bugs dont le type
sizeof(type)
est changé; chaque fois que vous modifiez le type d'une variable, vous devez effectuer une analyse rapide pour voir où cette variable est utilisée et si vous devez modifier dessizeof(type)
instructions. Même s'il y a toujours une chance de se tromper, cela présente un risque beaucoup plus faible que les erreurs d'indirection de pointeur.Un avantage
sizeof variable
est pour les tableaux, mais dans la pratique, j'ai constaté que le passage de tableaux en paires de premier / len est beaucoup plus courant (dans ce cas, utilisez simplement la longueur), et il est également très facile de se tromper de taille en raison de désintégration tableau / pointeur, comme dans cet exemple:la source
sizeof var
; si c'est un pointeur c'estsizeof *var
. C'est aussi quelque chose que les gens peuvent se tromper, et le compilateur le prendra volontiers sans se plaindre. Je soutiens que ces erreurs sont beaucoup plus difficiles à repérer et sont plus courantes que les erreurs desizeof(type)
forme.C
, la publication de code C est plus informative que le code C ++mat3_t::mat3_t(...)
.L'objectif est de supprimer la redondance. Si vous utilisez sizeof pour une opération liée à une variable, vous devez évidemment le refléter dans sizeof. Oui, vous pouvez gâcher comme dans le premier exemple, mais le remède n'est pas d'utiliser le type, mais * var, correspondant correctement au but.
Pour atténuer ces problèmes, il est habituel d'utiliser des macros, des modèles et des outils similaires formés pour le cas d'utilisation plutôt que sizeof nu.
Voir ma macro CLEAR qui est utilisée exclusivement au lieu d'un memset nu. J'ai sauvé mon cul plusieurs fois en cas de faute de frappe d'indirection ou lorsqu'un contenu de structure récupérait un vecteur ou une chaîne ...
la source
La logique métier définit votre choix.
Si votre code fait référence à une variable particulière et sans cette variable, votre code n'a aucun sens - choisissez
sizeof(var)
Si vous codez traite d'un ensemble de variables avec un type particulier - choisissez
sizeof(type)
. Habituellement, vous en avez besoin si vous en avez untypedef
qui définit de nombreuses variables que vous traitez différemment selon leur type (par exemple la sérialisation). Vous ne savez peut-être pas laquelle de ces variables restera dans les futures versions de code, donc choisir le type comme argument est logiquement correct. Même le changement de cestypedef
paramètres n'affectera pas votre taille de ligne.la source
Selon la taille de l'objectif (variable) pourrait être la meilleure solution. De cette façon, vous pouvez modifier votre type de variable si nécessaire, sans corriger toutes les entrées pour le type. Mais encore une fois, cela dépend de votre objectif.
la source