est une implémentation de C ++ standard autorisée à mettre en œuvre certains comportements qui sont définis par la mise en oeuvre dans la norme de cette manière qu'il est différent entre les différentes exécutions du même programme une fois le programme avec les mêmes données d'entrée? p>
Par exemple, une implémentation est autorisée à dire "le comportement est-ce le week-end et qu'autrement" et mettre en œuvre le comportement selon une telle déclaration? P>
6 Réponses :
Comportement défini sur la mise en œuvre signifie P>
comportement non spécifié où chaque implémentation documents forte> comment le choix est fait p> blockQuote>
Il est obligatoire em> pour les écrivains du compilateur pour documenter le comportement d'une construction de programmation particulière pour une implémentation particulière. P>
..... de cette manière qu'elle soit différente entre les différentes exécutions du même compilé une fois le programme avec les mêmes données d'entrée? P> blockQuote>
Nopes! P>
Par exemple, une implémentation est autorisée à dire "le comportement est-ce le week-end et qu'autrement" et mettre en œuvre le comportement selon une telle déclaration? P> blockQuote>
Je ne suis pas sûr, mais je pense que la réponse est
non forte>. p>
Je ne vois pas pourquoi cela n'est pas autorisé. La norme indique "Comment le choix est fait", pas "quel choix est fait".
Comme je le vois, la définition du comportement défini par la mise en œuvre donnée n'exclut pas la possibilité de différences à point à exécuter, à condition que cela documente exactement lorsque chaque cas se produise et exactement ce qui se passe pour chacun.
@shacharptooth: J'ai édité ma réponse, mais je suis presque certain que la réponse à la première question est non. Par exemple, compte tenu de Tailleof (int) code>, il est garanti (car la mise en œuvre a documenté le comportement) de rester corrigé pour une implémentation particulière. .... Je suis un peu confus par
et implémenter le comportement en fonction de cette déclaration? Code>
Une implémentation conforme peut assez facilement indiquer que tailleof (int) code> est 4 en semaine et 2 le week-end. Il n'est pas différent de dire que cela sera 2 si vous définissez
int_is_2_bytes code> ou 4 sinon. Tant que c'est documenté, tout va bien. Et le "4 en semaine, 2 sinon" la déclaration est entièrement i> cohérente - les numéros i> ne doivent pas être cohérents, juste la spécification i>. Bien sûr, après avoir dit cela, je dirais clairement un compilateur qui a fait cela :-)
Je pense que vous devez clarifier lorsque vous soupçonnez le changement. Le comportement ne changera pas entre 2 points du programme compilé. Il peut toutefois changer si vous compilez deux fois un programme (par exemple avec différents paramètres du compilateur).
@paxdiablo: ah! C'est pourquoi j'ai dit que je n'étais pas sûr de la réponse à sa deuxième question :). Mais je ne comprends toujours pas la réponse de Johannes à la première question. Voir mon commentaire sous son post.
@paxdiablo: Je dirais que cela correspondrait au libellé, mais pas à l'intention de la norme.
@paxdiablo: Un compilateur pourrait-il préciser légalement qu'un «non signé INT» en mémoire est de 16 bits, mais dans certaines circonstances, dans l'absence des typastes, les calculs intermédiaires avec «non signé INT» ne seront pas plus longs? Par exemple. Un compilateur pourrait-il préciser que (UI1 + UI2) >> 1 donnera une moyenne arrondi par arithmétiquement correcte? Je pense que cela pourrait pour "INT", mais cela pourrait-il pour "non signé INT"?
rand (3) code> dans
heure (3) code> dans
Comment est-ce pertinent à la question?
Sont rand () code> ou
heure () code> étiqueté définie par la mise en œuvre? Je ne peux que supposer qu'ils sont, et si oui, ils seraient vraiment un contre-exemple. Eh bien, sauf si vous considérez que l'état actuel et / ou l'état de la RNG System pour faire partie de l'entrée.
@naveen, j'ai supposé rand () code> est spécifié dans la norme mais les détails sont définis par la mise en œuvre. J'ai du mal à vérifier cette hypothèse.
Bien sûr, si les documents de mise en œuvre lorsque le comportement change exactement avec des courses différentes, c'est bien. Notez que le comportement défini par la mise en œuvre fait partie des paramètres de la machine abstraite: p>
Les descriptions sémantiques de cette norme internationale définissent un résumé indéterminé paramétré machine. p>
Certains aspects et opérations de la machine abstraite sont décrits dans cette norme internationale comme définie par la mise en œuvre (par exemple, Tailleof (int)). Celles-ci constituent les paramètres de la machine abstraite. Chaque mise en œuvre doit inclure la documentation décrivant ses caractéristiques et ses comportements à cet égard. Cette documentation doit définir l'instance de la machine abstraite qui correspond à cette mise en œuvre (appelée «instance correspondante» ci-dessous). P> blockQuote>
Cela ne permet pas de modifier le comportement en une seule fois du compilateur. Mais entre différentes pistes du compilateur, le compilateur peut utiliser une machine abstraite correspondante différente qui diffère selon différentes valeurs définies de la mise en œuvre, en fonction de la définition de la mise en œuvre. Les paramètres de ligne de commande comme
-wall code> (qui change l'ensemble de messages diagnostiques définis par la mise en œuvre) sont l'exemple le plus courant de cela. Ceci est une différence pour un comportement non spécifié en plus des exigences de la documentation. Le comportement non spécifié est beaucoup moins restrictif: p>
Certains autres aspects et opérations de la machine abstraite sont décrits dans la présente Norme internationale comme non spécifié (par exemple, ordre d'évaluation des arguments à une fonction). Dans la mesure du possible, cette norme internationale définit un ensemble de comportements admissibles. Celles-ci définissent les aspects non déterministes de la machine abstraite. Une instance de la machine abstraite peut donc avoir plus d'une séquence d'exécution possible pour un programme donné et une entrée donnée. P> blockQuote>
... Définissez une machine abstraite non déterministe paramétrée. CODE> Comme la machine abstraite est nondéterministe, comment est-il nécessaire que le comportement soit cohérent en une seule fois du compilateur?
@Prason, seulement quelques chemins - ceux où le comportement n'est pas spécifié - introduisez le non-déterminisme. Par exemple, l'expression régulière z (a | b) code> peut être exprimée par une machine à états finis non déterministe (NFA) qui correspond à
a code> ou
b < / code> à la fin de l'entrée. Mais toujours, il correspond toujours à
z code> au début de l'entrée :) maintenant pour le comportement défini par la mise en œuvre, si les paramètres (disent,
z code> au début) changeraient obtiendrait une autre machine abstraite correspondante résultante. Vous ne voudriez plus avoir qu'une seule implémentation traduit le code source, mais deux. :)
Ah !! Et la question de Sharpoth mentionne que les données d'entrée sont nécessaires être le même code> .... ESTEW! merci johannes :)
IIRC, système () est nécessaire pour exister, mais donné un comportement défini de la mise en œuvre. Quelque chose comme le système ("ls | grep foo") aura naturellement différents effets basés sur la question de savoir si votre système peut ou non exécuter quelque chose appelé LS, qui peut varier entre les courses. Et, même sur une machine unix assez normale où la LS et le GREP font ce que vous attendez et ne vous en résulterez pas, le résultat dépendra toujours de l'existence d'un fichier avec FOO dans le nom, qui sera certainement autorisé à varier temps et d'où le programme est exécuté, etc. Cela dépend simplement de l'endroit où vous dessinez la ligne de "les mêmes données d'entrée". Si la machine est dans un état parfaitement identique, vous pouvez vous attendre à un comportement identique, mais pas de deux points ne comportera une machine vraiment dans un état de pédantisme. (Même la température de la CPU dans des machines autrement parfaitement identiques pourrait entraîner un comportement de limitation, qui modifie le gagnant de certaines conditions de course, ce qui entraîne visiblement dans différents comportements de votre programme.) P>
Un exemple que je peux penser, c'est si le programme utilise une grande ou une petite représentation de Endian pour des chiffres. Je crois que cela compterait certainement comme comportement défini par la mise en œuvre. P>
sur certaines puces, par exemple certaines croustilles de bras, il est possible de changer de mode au moment de l'exécution afin que vous puissiez vouloir un compilateur pouvant produire un programme qui fonctionnerait dans l'une ou l'autre sens du comportement défini qui pourrait être un comportement défini qui pourrait être différent de la mise en œuvre. chaque exécution en fonction des paramètres externes. P>
De même, je suppose que vous pouvez écrire un compilateur qui produit à la fois 32 AD 64 bits compilés du même programme - et le mode qu'il a exécuté pourrait être déterminé au moment de l'exécution. Encore une fois, la documentation devrait dire que les INT étaient 32 bits ou 64 bits en fonction de la façon dont vous l'avez couru. p>
Pour être honnête, je ne peux voir personne de faire de ces choses, mais ils sonnent tous deux des exemples vaguement plausibles de ce que vous demandiez et je ne vois pas pourquoi ils ne seraient pas légaux sous la norme aussi longtemps que La documentation a correctement documenté la nature du comportement dépendant du système. P>
+1, dans les fichiers binaires universels de MacOSX contiennent à la fois une version 32 et 64 bits (dans les dernières versions MacOS X qui disposent de 64 bits de support) et vous pouvez choisir au moment du lancement de la version que vous souhaitez exécuter. Les fichiers binaires peuvent même contenir du code pour une architecture complètement différente en tant que PowerPC. Et au cas où vous vous demanderiez, c'est utile. Certains plugins de safari ne fonctionnent pas dans 64 bits, vous permettant ainsi de démarrer une session safari dans 32 bits lorsque vous en avez besoin.
Ah Nice, je ne savais pas que Maxosx a fait ceci :)
Les garanties sont ce que le compilateur a documenté. Différents drapeaux de compilateur ou différents état de l'ordinateur à la compilation peuvent affecter la manière dont le compilateur / optimiseur traite votre programme et qui peut avoir un effet sur le résultat. Avec les drapeaux du compilateur ayant le plus grand impact (le même compilateur peut être utilisé pour générer des programmes 32 et 64 bits dans un environnement 64 bits, dans les deux exigences d'alignement des exécutions peut différer). P>
Vous pouvez vous attendre à ce que, dans la plupart des cas, la mise en œuvre fournira des garanties de base sur le comportement de la mise en œuvre et le programme qu'il génère pour un ensemble donné de paramètres compilateurs / lieurs. Même si la charge du système peut affecter le montant de l'optimiseur peut fonctionner sur votre programme - des optimiseurs de ce programme seront attribués à une durée limitée - qui ne devrait pas modifier le comportement attendu. P>
Notez que, bien qu'il n'y ait aucune garantie, il serait difficile de commercialiser un compilateur qui produit du code avec des comportements différents en fonction des paramètres non liés comme la position de la lune par rapport aux étoiles. P>
Avez-vous un exemple concret à l'esprit? alternativement, je prendrais "la mise en œuvre définie" comme signifiant exactement que et si l'agent de mise en œuvre garantit une garantie de cohérence, alors que tous les paris sont désactivés.
GCC était beaucoup plus cool avec un comportement indéfini: fr.wikipedia.org/wiki/undefined_behavior#compiler_easter_egg S