Pourquoi sizeof est-il appelé un opérateur au moment de la compilation?

12

À l'origine, cela fait partie d' une autre question.

Pourquoi est-on sizeofappelé un opérateur de compilation? N'est-ce pas réellement un opérateur d'exécution? Et s'il s'agit bien d'un opérateur au moment de la compilation, comment peut-il aider à produire du code portable qui s'exécute de la même manière sur différents ordinateurs? Veuillez expliquer en détail.

Le codeur pacifique
la source
4
répondu en détail à SO: Pourquoi sizeof (x ++) n'incrémente-t-il pas x?
moucher
3
Comment prévoyez-vous que la taille d'un type change à l'exécution?
@MichaelT: La taille d'une instance d'un type peut certainement changer - il y a du polymorphisme de classe, après tout. Je dirais sizeof(polymorphic_ptr*)qu'être constant est assez contre-intuitif et tout simplement stupide. Oui, c'est la manière C ++, mais idiote quand même.
Rétablir Monica le
@KubaOber En effet. Je suis simplement curieux de savoir comment le PO a pensé qu'il devrait se comporter dans différents cas et j'espère obtenir un code qui démontrerait sa confusion à ce sujet pour aider à élargir la question.
4
Entré à voter la réponse "car il fonctionne au moment de la compilation", a laissé déçu.
Ben Jackson

Réponses:

23

sizeof()vous donne la taille du type de données , pas la taille d'une instance particulière de ce type en mémoire.

Par exemple, si vous disposiez d'un objet de données de chaîne qui allouait un tableau de caractères de taille variable au moment de l'exécution, sizeof()ne pouvait pas être utilisé pour déterminer la taille de ce tableau de caractères. Cela ne vous donnerait que la taille du pointeur.

La taille d'un type de données est toujours connue au moment de la compilation.


la source
3
Parce que C (++) n'a pas de métadonnées d'objet au moment de l'exécution, vous ne pouvez pas non plus vraiment obtenir ces choses au moment de l'exécution.
C. Ross
5
En fait, si vous utilisez sizeofsur un tableau, vous allez obtenir la taille du tableau (qui est le temps de la taille de l' élément , le nombre d'éléments). Mais si vous l'utilisez sur un pointeur, vous n'obtenez que la taille du pointeur. Donc, puisque dans la plupart des cas où vous souhaitez connaître la taille d'un tableau, vous n'avez qu'un pointeur, ce n'est pas du tout utile.
sepp2k
1
@Jens La question est balisée [C ++] et VLA n'est pas entrée dans la norme C ++.
authchir
13

parce que la taille entière de "l'appel" est calculée au moment de la compilation et tout ce qui se trouve entre les parenthèses est ignoré et non exécuté au moment de l'exécution,

le résultat est purement basé sur les informations de type statique disponibles pour le compilateur

monstre à cliquet
la source
7

Pourquoi sizeof est-il appelé un opérateur au moment de la compilation?

Parce qu'au moment de la compilation, le compilateur calcule la taille de l'expression et remplace cette valeur constante au moment de la compilation.

N'est-ce pas réellement un opérateur d'exécution?

Non. Vous pouvez même utiliser sizeofpour évaluer la taille des expressions que vous ne pouvez pas exécuter légalement (c'est-à-dire qui entraîneraient un comportement indéfini), tant que le compilateur peut déterminer quel est le type de l'expression.

De plus, même avant C ++ 11 constexpr, vous pouvez utiliser des sizeofexpressions de manière que vous ne pouvez pas utiliser d'expressions d'exécution.

Et s'il s'agit bien d'un opérateur au moment de la compilation, en quoi cela aide-t-il à produire du code portable ...

Les types peuvent varier en taille sur différentes plateformes. L'utilisation d' sizeofexpressions au lieu d'hypothèses codées en dur signifie que votre code ne se cassera pas lorsque vous compilerez sur une plateforme différente et que vos types changeront de taille.

Inutile
la source
1
Eh bien, je trouve que c'est la réponse la plus utile;). Bro (en supposant que vous soyez un homme), j'ai un doute. Voulez-vous dire que lorsque les gens disent que sizeof rend les programmes portables, cela signifie que le code source peut être compilé sans aucune erreur sur toutes les machines et cela ne signifie pas que le programme exécutable peut être exécuté sur n'importe quelle machine. Droite ? Si c'est vrai, mon doute est vraiment dissipé.
The Peaceful Coder
1
Oui, le code est portable, dans le sens où vous pouvez compiler un binaire correct (différent) pour chaque plate-forme.
Inutile
5

C ++ ne stocke pas réellement les métadonnées des objets au moment de l'exécution, donc la vérification de la taille doit être au moment de la compilation. Pour un exemple de la façon dont C ++ ne valide pas la taille, déclarez un tableau intd'une taille arbitraire et lisez après la fin de celui-ci. Si vous êtes chanceux, vous obtiendrez un, segfaultmais plus probablement, vous lirez simplement du charabia, car C ++ ne suit pas la taille de votre tableau.

Voir Un programme C / C ++ peut-il provoquer une erreur de segmentation après avoir lu après la fin d'un tableau (UNIX)? pour un exemple de SO.

Traverser
la source