C++Comportamiento indefinido


Introducción

¿Qué es el comportamiento indefinido (UB)? De acuerdo con la norma ISO C ++ (§1.3.24, N4296), es un "comportamiento por el que esta norma internacional no impone requisitos".

Esto significa que cuando un programa se encuentra con UB, se le permite hacer lo que quiera. A menudo, esto significa un choque, pero puede que simplemente no haga nada, haga que los demonios salgan volando por tu nariz , ¡o incluso parece que funciona correctamente!

No hace falta decir que debes evitar escribir código que invoque a UB.

Observaciones

Si un programa contiene un comportamiento indefinido, el estándar de C ++ no impone restricciones a su comportamiento.

  • Puede parecer que funciona según lo previsto por el desarrollador, pero también puede fallar o producir resultados extraños.
  • El comportamiento puede variar entre ejecuciones del mismo programa.
  • Cualquier parte del programa puede funcionar mal, incluidas las líneas que vienen antes de la línea que contiene un comportamiento indefinido.
  • La implementación no es necesaria para documentar el resultado de un comportamiento indefinido.

Una implementación puede documentar el resultado de una operación que produce un comportamiento indefinido de acuerdo con el estándar, pero un programa que depende de dicho comportamiento documentado no es portátil.

¿Por qué existe un comportamiento indefinido?

Intuitivamente, el comportamiento indefinido se considera algo malo, ya que tales errores no pueden manejarse con amabilidad mediante, por ejemplo, controladores de excepciones.

Pero dejar un comportamiento indefinido es en realidad una parte integral de la promesa de C ++ "no pagas por lo que no usas". El comportamiento indefinido permite que un compilador asuma que el desarrollador sabe lo que está haciendo y no introduce código para verificar los errores resaltados en los ejemplos anteriores.

Encontrar y evitar comportamientos indefinidos.

Algunas herramientas se pueden usar para descubrir un comportamiento indefinido durante el desarrollo:

  • La mayoría de los compiladores tienen marcas de advertencia para advertir sobre algunos casos de comportamiento indefinido en tiempo de compilación.
  • Las versiones más recientes de gcc y clang incluyen un indicador denominado "Desinfectante de comportamiento indefinido" ( -fsanitize=undefined ) que verificará el comportamiento indefinido en el tiempo de ejecución, a un costo de rendimiento.
  • lint herramientas similares a lint pueden realizar un análisis de comportamiento indefinido más completo.

Comportamiento indefinido, no especificado y definido por la implementación

De la sección 1.9 (Ejecución del programa) de la norma C ++ 14 (ISO / IEC 14882: 2014):

  1. Las descripciones semánticas en esta Norma Internacional definen una máquina abstracta no determinista parametrizada. [CORTAR]

  2. Ciertos aspectos y operaciones de la máquina abstracta se describen en esta Norma Internacional como definidos por la implementación (por ejemplo, sizeof(int) ). Estos constituyen los parámetros de la máquina abstracta . Cada implementación deberá incluir documentación que describa sus características y comportamiento en estos aspectos. [CORTAR]

  3. Ciertos otros aspectos y operaciones de la máquina abstracta se describen en esta Norma Internacional como no especificados (por ejemplo, evaluación de expresiones en un nuevo inicializador si la función de asignación no puede asignar memoria). Donde sea posible, esta norma internacional define un conjunto de comportamientos permitidos. Estos definen los aspectos no deterministas de la máquina abstracta. Una instancia de la máquina abstracta puede tener más de una ejecución posible para un programa dado y una entrada dada.

  4. Ciertas otras operaciones se describen en esta Norma Internacional como indefinidas (o ejemplo, el efecto de intentar modificar un objeto const ). [ Nota : esta Norma Internacional no impone requisitos sobre el comportamiento de los programas que contienen un comportamiento indefinido. - nota final ]

Comportamiento indefinido Ejemplos relacionados