una funcion declara constantes constante como c++ c++11 language-lawyer undefined-behavior c++14

funcion - ¿Ha cambiado el estándar C++ con respecto al uso de valores indeterminados y comportamiento indefinido en C++ 14?



funcion pi en c++ (1)

Como se describe en ¿La inicialización implica una conversión de valor l a valor? Es int x = x; UB? el estándar de C ++ tiene un ejemplo sorprendente en la sección 3.3.2 Punto de declaración en el que un int se inicializa con su propio valor indeterminado:

int x = 12; { int x = x; }

Aquí el segundo x se inicializa con su propio valor (indeterminado). - ejemplo final ]

La respuesta de Johannes a esta pregunta indica un comportamiento indefinido, ya que requiere una conversión de valor a validación.

En el último borrador del estándar N3936 C ++ 14 que se puede encontrar here este ejemplo ha cambiado a:

unsigned char x = 12; { unsigned char x = x; }

Aquí el segundo x se inicializa con su propio valor (indeterminado). - ejemplo final ]

¿Ha cambiado algo en C ++ 14 con respecto a los valores indeterminados y el comportamiento indefinido que ha impulsado este cambio en el ejemplo?


Sí, este cambio fue impulsado por cambios en el lenguaje que hacen que sea un comportamiento indefinido si la evaluación produce un valor indeterminado, pero con algunas excepciones para los caracteres angostos sin signo .

El informe de defectos 1787 cuyo texto propuesto se puede encontrar en N3914 1 fue aceptado recientemente en 2014 y está incorporado en el último borrador de trabajo N3936 :

El cambio más interesante con respecto a los valores indeterminados sería el párrafo 12 de la sección 8.5 que va desde:

Si no se especifica un inicializador para un objeto, el objeto se inicializa por defecto; si no se realiza la inicialización, un objeto con duración de almacenamiento automática o dinámica tiene un valor indeterminado. [ Nota: los objetos con duración estática o de almacenamiento de subprocesos se inicializan en cero, consulte 3.6.2. - nota final ]

a ( énfasis mío ):

Si no se especifica ningún inicializador para un objeto, el objeto se inicializa por defecto. Cuando se obtiene almacenamiento para un objeto con una duración de almacenamiento automática o dinámica, el objeto tiene un valor indeterminado , y si no se realiza una inicialización para el objeto, ese objeto conserva un valor indeterminado hasta que ese valor sea reemplazado (5.17 [expr.ass]) . [Nota: los objetos con duración estática o de almacenamiento de subprocesos se inicializan en cero, consulte 3.6.2 [basic.start.init]. -finalizar nota] Si una evaluación produce un valor indeterminado, el comportamiento no está definido excepto en los siguientes casos :

  • Si se produce un valor indeterminado del tipo de carácter anónimo sin signo (3.9.1 [basic.fundamental]) mediante la evaluación de:

    • el segundo o tercer operando de una expresión condicional (5.16 [expr.cond]),

    • el operando derecho de una coma (5.18 [expr.comma]),

    • el operando de un molde o conversión a un tipo de carácter anónimo sin signo (4.7 [conv.integral], 5.2.3 [expr.type.conv], 5.2.9 [expr.static.cast], 5.4 [expr.cast]) , o

    • una expresión de valor descartado (Cláusula 5 [expr]),

    entonces el resultado de la operación es un valor indeterminado.

  • Si se produce un valor indeterminado del tipo de carácter anónimo sin signo (3.9.1 [basic.fundamental]) mediante la evaluación del operando correcto de un operador de asignación simple (5.17 [expr.ass]) cuyo primer operando es un valor l de anotado estrecho tipo de carácter, un valor indeterminado reemplaza el valor del objeto referido por el operando izquierdo.

  • Si un valor indeterminado del tipo de carácter anónimo sin signo (3.9.1 [basic.fundamental]) es producido por la evaluación de la expresión de inicialización al inicializar un objeto de tipo de carácter angosto sin signo, ese objeto se inicializa a un valor indeterminado.

e incluido el siguiente ejemplo:

[ Ejemplo:

int f(bool b) { unsigned char c; unsigned char d = c; // OK, d has an indeterminate value int e = d; // undefined behavior return b ? d : 0; // undefined behavior if b is true }

- ejemplo final ]

Podemos encontrar este texto en here que es el borrador actual y N3937 es el C++14 DIS .

Antes de C ++ 1y

Es interesante observar que antes de este borrador, a diferencia de C, que siempre tuvo una noción bien especificada de qué usos de los valores indeterminados estaban indefinidos, C ++ utilizó el término valor indeterminado sin siquiera definirlo ( asumiendo que no podemos tomar prestada la definición de C99 ) y también ver el informe de defectos 616 . Tuvimos que basarnos en la conversión devaluado avalor no especificado, que en el borrador del estándar C ++ 11 se trata en la sección 4.1 Conversión devalor avaluadas, párrafo 1, que dice:

[...] si el objeto no está inicializado, un programa que necesita esta conversión tiene un comportamiento indefinido. [...]

Notas al pie:

  1. 1787 es una revisión del informe de defectos 616 , podemos encontrar esa información en N3903