Tout d'abord, j'ai l'impression que nous devons clarifier certains termes, au moins en ce qui concerne C.
De la Projet en ligne C2011 :
-
Comportement indéfini - comportement, lors de l'utilisation d'une construction de programme non portable ou erronée ou de données erronées, pour lesquels la présente Norme internationale n'impose aucune exigence. Le comportement indéfini possible va de l'ignorance totale de la situation avec des résultats imprévisibles, à un comportement pendant la traduction ou la programmation. imprévisibles, à se comporter pendant la traduction ou l'exécution du programme d'une manière documentée et caractéristique de l'environnement (avec ou sans émission d'un avis de conformité). l'environnement (avec ou sans l'émission d'un message de diagnostic), à l'interruption d'une traduction ou d'une exécution (avec l'émission d'un message de diagnostic). ou l'exécution (avec l'émission d'un message de diagnostic).
-
Comportement non spécifié - l'utilisation d'une valeur non spécifiée, ou tout autre comportement pour lequel la présente Norme internationale prévoit deux possibilités ou plus et n'impose pas d'autres exigences quant à celle qui est choisie dans un cas donné. cas. L'ordre dans lequel les arguments d'une fonction sont évalués est un exemple de comportement non spécifié. évalués.
-
Comportement défini par la mise en œuvre - un comportement non spécifié où chaque implémentation documente comment le choix est fait. Un exemple de comportement défini par l'implémentation est la propagation du bit de poids fort lorsqu'un nombre entier signé est décalé vers la droite.
Le point clé ci-dessus est que non spécifié comportement signifie que la définition du langage fournit plusieurs valeurs ou comportements parmi lesquels l'implémentation peut choisir, et qu'il n'y a pas d'autres exigences sur la façon dont ce choix est fait. Un comportement non spécifié devient définie par la mise en œuvre comportement lorsque la mise en œuvre documente la manière dont elle fait ce choix.
Cela signifie qu'il existe des restrictions sur ce qui peut être considéré comme un comportement défini par l'implémentation.
L'autre point essentiel est que indéfini ne signifie pas illégal cela signifie seulement imprévisible . Cela signifie que vous avez annulé la garantie, et que tout ce qui se passe ensuite n'est pas de la responsabilité de l'implémentation du compilateur. Un résultat possible du comportement indéfini est de travailler exactement comme prévu sans effets secondaires désagréables. Ce qui, franchement, est le pire résultat possible, car cela signifie que dès que quelque chose dans le code ou l'environnement change, tout peut exploser sans que vous sachiez pourquoi (j'ai vu ce film plusieurs fois).
Venons-en maintenant à la question qui nous occupe :
Je sais aussi que sur certaines architectures ("machine segmentée" comme je l'ai lu quelque part), il y a de bonnes raisons pour que le comportement soit indéfini.
Et c'est pourquoi c'est indéfini. partout . Il existe encore des architectures dans lesquelles des objets différents peuvent être stockés dans des segments de mémoire différents, et toute différence dans leurs adresses serait sans signification. Il existe tellement de modèles de mémoire et de schémas d'adressage différents que l'on ne peut espérer définir un comportement qui fonctionne de manière cohérente pour tous (ou alors la définition serait si compliquée qu'elle serait difficile à mettre en œuvre).
La philosophie du C est d'être le plus portable possible sur le plus grand nombre d'architectures possible, et pour cela, il impose le moins d'exigences possible à l'implémentation. C'est pourquoi les types arithmétiques standard ( int
, float
etc.) sont définis par le plage minimale de valeurs qu'ils peuvent représenter avec un précision minimale et non par le nombre de bits qu'ils occupent. C'est pourquoi les pointeurs de différents types peuvent avoir des tailles et des alignements différents.
L'ajout d'un langage qui rendrait certains comportements non définis sur cette liste d'architectures par rapport à non spécifiés sur cette liste d'architectures serait une maux de tête à la fois pour le comité de normalisation et pour divers compilateurs. Cela signifierait ajouter beaucoup de logique de cas spéciaux à des compilateurs comme gcc
ce qui pourrait le rendre moins fiable en tant que compilateur.