Comment le code est-il stocké et exécuté sur la machine abstraite C ++?
Dans le premier livre que j'ai lu sur C ++, il est allé un peu dans les détails de la façon dont le code est réellement exécuté sur une machine (il a mentionné le compteur de programme, la pile d'appels, les adresses de retour, etc.). J'ai trouvé vraiment fascinant d'apprendre comment ça marche, même si je suis conscient qu'il n'est pas vraiment nécessaire de savoir comment fonctionne l'ordinateur pour écrire du bon code.
En lisant sur les mêmes sujets sur ce site de questions / réponses, j'ai découvert que cela ne doit en aucun cas être la façon dont j'avais appris auparavant, car ce que j'avais lu n'était qu'une certaine implémentation de C ++, en fonction de certains ordinateurs architecture et un certain compilateur. Le code C ++ pourrait aussi bien fonctionner sur quelque chose de complètement différent, à condition que l'on ait un compilateur conforme qui se comporte de la «bonne» façon. La bonne manière est alors définie par la norme et le comportement d'une "machine abstraite" (j'espère avoir bien compris jusqu'à présent).
Bien sûr, j'aimerais toujours savoir si des concepts tels que le segment de code de la mémoire ou le compteur de programmes sont toujours "d'une manière ou d'une autre" représentés dans la norme, et s'ils le sont, dans quelle mesure sont-ils représentés? Comment le concept de code-morceaux exécuté les uns après les autres est-il décrit dans la machine abstraite?
Puisqu'il a été demandé dans un commentaire si j'aimerais que le standard me soit répété: je n'ai pas pu comprendre le standard assez bien pour cerner exactement ce qu'il dit sur la machine abstraite / OU quelles déclarations de la norme peuvent être interprété comme des déclarations sur un concept abstrait de "compteur de programme" "Stockage de code" ... etc. Donc oui, par incapacité, je demande à la communauté d'interpréter ce qui est écrit dans la norme. Le résultat attendu de cette interprétation est la conception la plus détaillée de la structure interne de la machine abstraite qui correspond toujours au critère d'être «abstrait».
Réponses
Réponse courte: ce n'est pas le cas.
Nous n'exécutons pas réellement de code sur la machine abstraite de la spécification C ++ (ou sur toute machine abstraite - d'autres langages les définissent également). Nous exécutons du code sur des machines réelles implémentées avec des transistors, ou dans des logiciels fonctionnant sur des transistors. La machine abstraite dans la spécification du langage est utilisée pour définir les limites de ce que fera le code sur la machine réelle - elle doit fonctionner "comme si" elle s'exécutait sur la machine abstraite, au moins autant que l'apparence à l'environnement de la définition de la machine abstraite est concernée.
La citation pertinente de la norme est:
Une implémentation conforme exécutant un programme bien formé produira le même comportement observable que l'une des exécutions possibles de l'instance correspondante de la machine abstraite avec le même programme et la même entrée.
Il n'y a cependant pas de véritable définition solide de ce qu'est exactement le «comportement observable».
Alors pourquoi même définir ces machines abstraites? Eh bien, principalement parce qu'il existe de nombreuses machines réelles différentes et que vous voulez dire que votre code fonctionnera de la même manière sur n'importe laquelle d'entre elles. Les vraies machines sont également très complexes et difficiles à raisonner. Ainsi, la spécification du langage définit une machine abstraite qui est une simplification des types de machines réelles sur lesquelles elle s'attend à fonctionner. Particulièrement en ce qui concerne les détails de la façon dont le code est stocké et exécuté, ces détails sont pour la plupart "abstraits" dans la machine abstraite - cela ne spécifie pas, donc une implémentation peut utiliser tous les mécanismes fournis par la cible réelle tout en restant conforme la spécification.
La norme ne spécifie pas comment la machine abstraite fonctionne en interne, c'est tout le point. Ce concept est utilisé pour faire abstraction du fonctionnement interne des machines physiques.
le segment de code de la mémoire ou le compteur de programme sont toujours "en quelque sorte" représentés dans la norme
Non. La norme dit simplement (grosso modo) que les instructions sont exécutées séquentiellement, explique l' ordre d'évaluation , etc. Elle n'a pas de notion d'instructions de processeur ou de compteur de programme. Les pointeurs de fonction sont décrits comme complètement opaques, pointant vers des «fonctions» plutôt que vers des instructions individuelles. Cela ne garantit même pas que les fonctions sont stockées dans la même mémoire que les données.
La norme n'introduit pas non plus les concepts de pile et de tas. Il décrit uniquement la durée de vie des objets créés de différentes manières. Les pointeurs sont soigneusement décrits pour ne pas les limiter à des scalaires. Il n'y a pas de notion de registres, de cache, ...