[c++] ¿La inicialización implica una conversión de valor a validación? Es `int x = x;` ¿UB?



Answers

Una secuencia de conversión implícita de una expresión e a tipo T se define como equivalente a la siguiente declaración, utilizando t como resultado de la conversión (categoría de valor de módulo, que se definirá en función de T ), 4p3 y 4p6

T t = e;

El efecto de cualquier conversión implícita es lo mismo que realizar la declaración e inicialización correspondiente y luego usar la variable temporal como resultado de la conversión.

En la cláusula 4, la conversión de una expresión a un tipo siempre produce expresiones con una propiedad específica. Por ejemplo, la conversión de 0 a int* produce un valor de puntero nulo y no solo un valor de puntero arbitrario. La categoría de valor también es una propiedad específica de una expresión y su resultado se define de la siguiente manera

El resultado es un lvalue si T es un tipo de referencia lvalue o una referencia rvalue al tipo de función (8.3.2), un valor x si T es una referencia rvalue al tipo de objeto, y un prvalue en caso contrario.

Por lo tanto, sabemos que en int t = e; , el resultado de la secuencia de conversión es un valor pr, porque int es un tipo que no es de referencia. Entonces, si proporcionamos un glvalue, obviamente necesitamos una conversión. 3.10p2 aclara que para no dejar dudas

Siempre que aparezca un glvalue en un contexto donde se espera un prvalue, el glvalue se convierte en un prvalue; ver 4.1, 4.2 y 4.3.

Question

El estándar de C ++ contiene un ejemplo semi famoso de búsqueda de nombres "sorprendente" en 3.3.2, "Punto de declaración":

int x = x;

Esto inicializa x consigo mismo, que (siendo un tipo primitivo) no está inicializado y, por lo tanto, tiene un valor indeterminado (suponiendo que sea una variable automática).

¿Es este comportamiento realmente indefinido?

De acuerdo con 4.1 "conversión Lvalue-a -valor", es un comportamiento indefinido realizar una conversión lvalor-avalor en un valor no inicializado. ¿La mano derecha x sufre esta conversión? De ser así, ¿el ejemplo realmente tendría un comportamiento indefinido?




El comportamiento no está indefinido. La variable no está inicializada y se mantiene con cualquier valor aleatorio con el que comiencen los valores no inicializados. Un ejemplo de la demanda de prueba clan'g:

int test7b(int y) {
  int x = x; // expected-note{{variable 'x' is declared here}}
  if (y)
    x = 1;
  // Warn with "may be uninitialized" here (not "is sometimes uninitialized"),
  // since the self-initialization is intended to suppress a -Wuninitialized
  // warning.
  return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
}

Que puedes encontrar en las clang/test/Sema/uninit-variables.c para este caso explícitamente.




Links