c++ terminology definition

c++ - ¿Qué significa exactamente "IB" y "UB"?



terminology definition (5)

He visto los términos "IB" y "UB" utilizados varias veces, particularmente en el contexto de C ++. Intenté buscarlos en Google, pero aparentemente esas combinaciones de dos letras tienen un gran uso. :PAG

Entonces, te pregunto ... ¿qué significan cuando se dice que son algo malo?


Comportamiento definido por la implementación y comportamiento Indefinido

El estándar de C ++ es muy específico sobre los efectos de varios constructos, y en particular siempre debe tener en cuenta estas categorías de problemas :

  • El comportamiento indefinido significa que no hay absolutamente ninguna garantía. El código podría funcionar, o podría incendiar tu disco duro o hacer que los demonios salgan por tu nariz . En lo que respecta al lenguaje C ++, absolutamente cualquier cosa podría suceder. En términos prácticos, esto generalmente significa que tiene un error irrecuperable. Si esto sucede, no puedes confiar realmente en nada sobre tu aplicación (porque uno de los efectos de este comportamiento indefinido podría haber sido confundir la memoria utilizada por el resto de tu aplicación). No es necesario que sea coherente, por lo que ejecutar el programa dos veces podría dar resultados diferentes. Puede depender de las fases de la luna, el color de la camisa que llevas puesta o absolutamente cualquier otra cosa.

  • Comportamiento no especificado significa que el programa debe hacer algo sano y consistente, pero no es necesario documentar esto.

  • El comportamiento definido por la implementación es similar a no especificado, pero también debe ser documentado por los escritores del compilador. Un ejemplo de esto es el resultado de un reinterpret_cast . generalmente , simplemente cambia el tipo de un puntero, sin modificar la dirección, pero el mapeo en realidad está definido por la implementación, por lo que un compilador podría mapear a una dirección completamente diferente, siempre que documente esta opción. Otro ejemplo es el tamaño de un int. Al estándar C ++ no le importa si es de 2, 4 u 8 bytes, pero debe estar documentado por el compilador

Pero común para todos estos es que es mejor evitarlos. Cuando sea posible, cumpla con el comportamiento que está 100% especificado por el estándar C ++. De esta forma, se garantiza la portabilidad.

A menudo también debe confiar en un comportamiento definido por la implementación. Puede ser inevitable, pero igual debe prestarle atención, y tenga en cuenta que confía en algo que puede cambiar entre compiladores diferentes.

El comportamiento indefinido, por otro lado, siempre debe evitarse. En general, debes asumir que hace que tu programa explote de una forma u otra.


La versión corta:

Comportamiento definido por la implementación (IB): Correctamente programado pero indeterminado *

Comportamiento indefinido (UB): Programado incorrectamente (es decir, un error !)

*) "indeterminado" en lo que respecta al estándar de lenguaje, por supuesto será determinado en cualquier plataforma fija.



IB: Comportamiento definido por la implementación. El estándar deja que el compilador / plataforma particular defina el comportamiento preciso, pero requiere que se defina.

Usar el comportamiento definido por la implementación puede ser útil, pero hace que su código sea menos portátil.

UB: Comportamiento indefinido. El estándar no especifica cómo debe comportarse un programa que invoque un comportamiento indefinido. También conocido como "demonios nasales" porque teóricamente podría hacer que los demonios salgan volando de tu nariz.

Usar un comportamiento indefinido casi siempre es una mala idea. Incluso si parece funcionar a veces, cualquier cambio en el entorno, compilador o plataforma puede romper su código al azar.


  • IB: comportamiento definido de implementación: el compilador debe documentar lo que hace. Realizar una operación >> con un valor negativo es un ejemplo.

  • UB: comportamiento indefinido: el compilador puede hacer cualquier cosa, incluso simplemente bloqueando o dando resultados impredecibles. La desreferenciación de un puntero nulo entra en esta categoría, pero también cosas más sutiles como la aritmética del puntero que cae fuera de los límites de un objeto de matriz.

Otro término relacionado es "comportamiento no especificado". Esto es una especie de comportamiento definido e indefinido. para un comportamiento no especificado, el compilador debe hacer algo de acuerdo con el estándar, pero exactamente qué opciones le da el estándar depende del compilador y no necesita ser definido (o incluso consistente). Cosas como el orden de evaluación de las subexpresiones entran en esta categoría. El compilador puede realizar estos en el orden que desee, y podría hacerlo de manera diferente en diferentes compilaciones o incluso en diferentes ejecuciones de la misma compilación (poco probable, pero permitido).