¿Cuáles son todos los comportamientos indefinidos comunes que un programador de C ++ debe conocer?
Diga, como:
a[i] = i++;
c++
undefined
undefined-behavior
c++-faq
yesraaj
fuente
fuente
Respuestas:
Puntero
NULL
punteromemcpy
para copiar buffers superpuestos .El buffer se desborda
Desbordamientos de enteros
int64_t i = 1; i <<= 72
no está definido)Tipos, Reparto y Const
int i; i++; cout << i;
)volatile
osig_atomic_t
al recibir una señalFunción y plantilla
OOP
Archivo fuente y preprocesamiento
long int
#if
expresiónPara ser clasificado
fuente
El orden en que se evalúan los parámetros de la función es el comportamiento no especificado . (Esto no hará que su programa se bloquee, explote u ordene pizza ... a diferencia del comportamiento indefinido ).
El único requisito es que todos los parámetros deben evaluarse completamente antes de llamar a la función.
Esta:
Puede ser equivalente a esto:
O esto:
Puede ser cualquiera; depende del compilador. El resultado puede importar, dependiendo de los efectos secundarios.
fuente
El compilador es libre de reordenar las partes de evaluación de una expresión (suponiendo que el significado no haya cambiado).
De la pregunta original:
Doble comprobación de bloqueo. Y un error fácil de cometer.
fuente
Mi favorita es "La recursión infinita en la creación de instancias de plantillas" porque creo que es la única en la que el comportamiento indefinido ocurre en el momento de la compilación.
fuente
Asignación a una constante después de despojar
const
usandoconst_cast<>
:fuente
Además del comportamiento indefinido , también existe el comportamiento igualmente desagradable definido por la implementación .
El comportamiento indefinido ocurre cuando un programa hace algo cuyo resultado no está especificado por el estándar.
El comportamiento definido por la implementación es una acción de un programa cuyo resultado no está definido por el estándar, pero que la implementación debe documentar. Un ejemplo es "Literales de caracteres multibyte", de la pregunta de desbordamiento de pila ¿Hay un compilador de C que no puede compilar esto? .
El comportamiento definido por la implementación solo lo muerde cuando comienza a portar (¡pero actualizar a una nueva versión del compilador también es portar!)
fuente
Las variables solo pueden actualizarse una vez en una expresión (técnicamente una vez entre puntos de secuencia).
fuente
Una comprensión básica de los diversos límites ambientales. La lista completa se encuentra en la sección 5.2.4.1 de la especificación C. Aquí hay algunos;
En realidad, me sorprendió un poco el límite de 1023 etiquetas de caso para una declaración de cambio, puedo prever que se supere con bastante facilidad para el código / lex / analizador generado.
Si se exceden estos límites, tiene un comportamiento indefinido (fallas, fallas de seguridad, etc.).
Correcto, sé que esto es de la especificación C, pero C ++ comparte estos soportes básicos.
fuente
Utilizando
memcpy
para copiar entre regiones de memoria superpuestas. Por ejemplo:El comportamiento no está definido de acuerdo con el Estándar C, que está incluido en el Estándar C ++ 03.
7.21.2.1 La función memcpy
7.21.2.2 La función memmove
fuente
El único tipo para el que C ++ garantiza un tamaño es
char
. Y el tamaño es 1. El tamaño de todos los demás tipos depende de la plataforma.fuente
Los objetos de nivel de espacio de nombres en unidades de compilación diferentes nunca deberían depender unos de otros para la inicialización, porque su orden de inicialización no está definido.
fuente