c++ language-lawyer c++14 constexpr lvalue-to-rvalue

c++ - Comprender el ejemplo de conversión de valor a valor



language-lawyer c++14 (1)

Me cuesta entender cómo este código (un ejemplo del borrador del estándar C ++ 14 [conv.lval] ) invoca un comportamiento indefinido para g(false) . ¿Por qué constexpr hace que el programa sea válido?

Además, ¿qué significa "no accede a yn "? En ambas llamadas a g() estamos devolviendo el miembro de datos n , entonces ¿por qué la última línea dice que no accede a él?

struct S { int n; }; auto f() { S x { 1 }; constexpr S y { 2 }; return [&](bool b) { return (b ? y : x).n; }; } auto g = f(); int m = g(false); // undefined behavior due to access of x.n outside its // lifetime int n = g(true); // OK, does not access y.n


Esto se debe a que yn no se usa odr y, por lo tanto, no requiere acceso a yn las reglas para el uso de odr están cubiertas en 3.2 y dice:

Una variable x cuyo nombre aparece como una expresión potencialmente evaluada, ex, se usa odr, a menos que la aplicación de la conversión lvalue-to-rvalue (4.1) a x produzca una expresión constante (5.19) que no invoque ninguna función no trivial y, si x es un objeto, ex es un elemento del conjunto de resultados potenciales de una expresión e, donde la conversión lvalue-to-rvalue (4.1) se aplica a e , oe es una expresión de valor descartado

Tenga en cuenta que Ben Voigt hizo algunos comentarios útiles que aclararon esto un poco. Entonces, la suposición de trabajo aquí es que x sería:

y

y e sería ( la expresión diferente para la que se define e se trata en el párrafo 2 de la sección 3.2 ):

(b ? y : x).n

y produce una expresión constante y la conversión de valor a valor se aplica a la expresión e .

Dado que f produce una lambda que captura las variables locales de f por referencia x ya no es válida una vez que se realiza la llamada a f ya que x es una variable automática dentro de f . Dado que y es una expresión constante , actúa como si no se accediera a yn y, por lo tanto, no tenemos el mismo problema de por vida.

Su ejemplo se incluye en N3939 sección 4.1 [conv.lval] y justo antes de ese ejemplo dice:

Cuando se aplica una conversión lvalue-to-rvalue a una expresión e, y

e incluye la siguiente viñeta a la que pertenece el examen:

la evaluación de e da como resultado la evaluación de un miembro ex del conjunto de resultados potenciales de e, y ex nombra una variable x que no es odr-utilizada por ex (3.2),

entonces:

no se accede al valor contenido en el objeto referenciado

Esto se aplicó al borrador del estándar C ++ 14 debido al informe de defectos 1773 .