¿Por qué se destruyen los objetos sin nombre de C ++ antes de que finalice el bloque del osciloscopio?

El siguiente código imprime uno, dos, tres. ¿Es eso deseado y cierto para todos los comstackdores de C ++?

class Foo { const char* m_name; public: Foo(const char* name) : m_name(name) {} ~Foo() { printf("%s\n", m_name); } }; void main() { Foo foo("three"); Foo("one"); // un-named object printf("two\n"); } 

Una variable temporal vive hasta el final de la expresión completa en la que se creó. La tuya termina en el punto y coma.

Esto está en 12.2 / 3:

Los objetos temporales se destruyen como el último paso en la evaluación de la expresión completa (1.9) que (léxicamente) contiene el punto donde se crearon.

Tu comportamiento está garantizado

Hay dos condiciones que, si se cumplen, extenderán la vida útil de un temporal. El primero es cuando se trata de un inicializador para un objeto. El segundo es cuando una referencia se une a un temporal.

Las reglas que rigen la vida útil de los objetos temporales no tienen nada que ver con la noción de scope . El scope es una propiedad de un nombre , y los objetos temporales no tienen nombres. En otras palabras, los objetos temporales no tienen scope.

La mayoría de las veces, la vida útil de un objeto temporal finaliza al final de la expresión completa que creó ese objeto, que es lo que observó en su experimento. Esta es la regla general que tiene algunas excepciones. El principal es que si adjuntas inmediatamente una referencia a tu objeto temporal, la vida útil del objeto se ampliará para coincidir con la duración de la referencia.

 const Foo &rfoo = Foo("one"); 

El temporal anterior vivirá mientras viva.

El scope de un objeto temporal como ese es solo una línea. Piénselo, ya no puede hacer referencia a él una vez que la línea termina, entonces, ¿por qué el objeto se mantendrá?

Si este no fuera el caso, los comstackdores no podrían optimizar los objetos temporales en las llamadas a funciones.

Sí, es deseado.

Foo foo("three") crea un objeto normal que se destruirá cuando finalice el scope.

Foo("one") crea un objeto temporal, que se destruye al final de la instrucción [1]. ¿Por qué? Porque no hay forma de que pueda acceder una vez que la instrucción haya finalizado.

[1] Simplificación deliberada: debería haber dicho el punto de secuencia .

Porque el comité de normas hizo tonterías. Lo hace porque eligieron hacerlo hacerlo. Está definido para hacerlo de esta manera. Debe considerarse una instancia anónima con scope igual que si hubiera sido nombrado. Desde el punto de instanciación hasta el final del bloque. Al parecer, pensaron que el único uso era pasar los temporales a funciones en las que se empujaban en la stack y salían de la stack al final de una llamada de función …

Un objeto sin nombre aún debe ser empujado a la stack y permanecer en la stack hasta que el bloque termine, saliéndolo de la stack cuando se espera. Construir y destruir un objeto durante una sola statement no tiene sentido. Me gustaría ver una sola instancia / caso donde esto sea realmente útil. Si no permanece en el scope durante la duración del locking, sin duda debería ser un error y, como mínimo, debería generar una advertencia.