J'ai vu les termes «IB» et «UB» utilisés plusieurs fois, en particulier dans le contexte de C ++. J'ai essayé de les rechercher sur Google, mais apparemment, ces combinaisons de deux lettres sont très utiles. : P
Alors, je vous demande ... qu'est-ce que cela veut dire, quand on dit que c'est une mauvaise chose?
Réponses:
IB: Comportement défini par l'implémentation. Le standard laisse le soin au compilateur / plateforme particulier de définir le comportement précis, mais exige qu'il soit défini.
L'utilisation d'un comportement défini par l'implémentation peut être utile, mais rend votre code moins portable.
UB: comportement indéfini. La norme ne spécifie pas comment un programme invoquant un comportement non défini doit se comporter. Aussi connu sous le nom de «démons nasaux», car théoriquement cela pourrait faire voler des démons hors de votre nez.
Utiliser un comportement non défini est presque toujours une mauvaise idée. Même si cela semble parfois fonctionner, toute modification de l'environnement, du compilateur ou de la plate-forme peut casser votre code de manière aléatoire.
la source
Comportement défini par l'implémentation et comportement indéfini
La norme C ++ est très spécifique sur les effets de diverses constructions, et en particulier, vous devez toujours être conscient de ces catégories de problèmes :
Un comportement non défini signifie qu'il n'y a absolument aucune garantie donnée. Le code pourrait fonctionner, mettre le feu à votre disque dur ou faire voler des démons dans votre nez . En ce qui concerne le langage C ++, absolument tout peut arriver. Concrètement, cela signifie généralement que vous avez un bogue irrécupérable. Si cela se produit, vous ne pouvez pas vraiment confiance quoi que ce soit au sujet de votre application (parce que l' un des effets de ce comportement non défini pourrait tout simplement avoir été gâcher la mémoire utilisée par le reste de votre application). Il n'est pas nécessaire d'être cohérent, donc exécuter le programme deux fois peut donner des résultats différents. Cela peut dépendre des phases de la lune, de la couleur de la chemise que vous portez ou de tout autre chose.
Un comportement non spécifié signifie que le programme doit faire quelque chose de sain et de cohérent, mais il n'est pas nécessaire de le documenter .
Le comportement défini par l'implémentation est similaire à non spécifié, mais doit également être documenté par les rédacteurs du compilateur. Un exemple de ceci est le résultat d'un
reinterpret_cast
. généralement , il change simplement le type d'un pointeur, sans modifier l'adresse, mais le mappage est en fait défini par l'implémentation, de sorte qu'un compilateur peut mapper vers une adresse complètement différente, tant qu'il a documenté ce choix. Un autre exemple est la taille d'un int. La norme C ++ ne se soucie pas si elle est de 2, 4 ou 8 octets, mais elle doit être documentée par le compilateurMais il vaut mieux les éviter. Lorsque cela est possible, respectez le comportement spécifié à 100% par le standard C ++ lui-même. De cette façon, vous êtes assuré de la portabilité.
Vous devez souvent également vous fier à un comportement défini par l'implémentation. Cela peut être inévitable, mais vous devez toujours y prêter attention et être conscient que vous comptez sur quelque chose qui peut changer entre les différents compilateurs.
Par contre, les comportements non définis doivent toujours être évités. En général, vous devez simplement supposer que cela fait exploser votre programme d'une manière ou d'une autre.
la source
IB: est le comportement défini par l'implémentation - le compilateur doit documenter ce qu'il fait. L'exécution d'une
>>
opération sur une valeur négative en est un exemple.UB: comportement indéfini - le compilateur peut tout faire, y compris simplement planter ou donner des résultats imprévisibles. Le déréférencement d'un pointeur nul entre dans cette catégorie, mais aussi des choses plus subtiles comme l'arithmétique du pointeur qui tombe en dehors des limites d'un objet tableau.
Un autre terme apparenté est «comportement non spécifié». C'est en quelque sorte entre les comportements définis par l'implémentation et les comportements indéfinis. pour un comportement non spécifié, le compilateur doit faire quelque chose selon le standard, mais les choix que le standard lui donne appartiennent au compilateur et n'ont pas besoin d'être définis (ni même cohérents). Des choses comme l'ordre d'évaluation des sous-expressions appartiennent à cette catégorie. Le compilateur peut les exécuter dans l'ordre de son choix et pourrait le faire différemment dans différentes versions ou même dans différentes exécutions de la même version (peu probable, mais autorisé).
la source
La version courte:
Comportement défini par l'implémentation (IB): correctement programmé mais indéterminé *
Comportement indéfini (UB): mal programmé (ie un bug !)
*) "indéterminé" en ce qui concerne le standard de langue, il sera bien entendu déterminé sur toute plateforme fixe.
la source
UB: comportement indéfini
IB: Comportement défini par l'implémentation
la source