2010-07-05 19 views
37

Considere el siguiente código:Salir de un bloque: ¿se llama a los destructores?

void foo() 
{ 
    { 
     CSomeClass bar; 

     // Some code here... 

     goto label; 

     // and here... 
    } 

label: 
    // and here... 
} 

¿El destructor de la barra se llama?

+0

¿Por qué necesita saber esto? 'goto' tiene sentido en el código generado, pero de todos modos puede y debe evitar objetos con destructores. – MSalters

+13

@MSalters: eso no tiene sentido, ¿por qué deberías evitar objetos con destructores? –

+1

@Viktor: Permítame expandir la segunda parte de la oración: _En el código generado_, puede y debe evitar objetos con destructores de todos modos. El uso canónico de 'goto' está en el código FSM generado. Aquí los saltos ocurren hacia atrás y hacia adelante, sin tener en cuenta los estados de código de estado que simplemente están en el medio. Los estados de FSM simplemente no son lineales, pero el código de C++ debe serlo. – MSalters

Respuesta

52

El estándar de C++ dice:

a la salida de un ámbito (sin embargo consumado), destructores (12.4) son llamada para todos los objetos construidos con una duración de almacenamiento automático (3.7.2) (llamado o bjects o temporales) que se declaran en ese ámbito, en en el orden inverso de su declaración .

Entonces la respuesta es "sí".

+0

Gracias. Eso es lo que necesitaba. –

9

1) Sí. 2) No hagas esto.

Elaboración: conceptualmente, esto no es diferente de dejar un bucle a través de break. goto, sin embargo, se desaconseja enérgicamente. Casi nunca es necesario usar goto, y cualquier uso debe ser analizado para averiguar qué está pasando.

+0

Respuesta perfecta. – Mizipzor

+1

2) haces esto cuando escapas bucles en realidad. –

+14

En realidad, goto tiene sentido en bastantes circunstancias. –

21

Sí, se llamarán.

Actualización: (.. Que está bien hacer esto, GOTOS no es peor que lanzar excepciones ficticias o el uso de Bools/IFS para salir de las cosas Un simple Goto dentro de una función no lo hacen código espagueti)

+7

+1 para negar al estudiante egoísta que sintió la necesidad de rechazar porque personalmente piensan que los gotos son malvados. Gotos tiene usos válidos, personas, independientemente de lo que le hayan dicho sus profesores. – KevenK

+2

"está bien hacer esto, no es peor que arrojar excepciones ficticias o usar bools/ifs para salir de cosas" Lanzar una excepción ficticia es una manera terrible de hacer esto (arrojar excepciones es generalmente extremadamente costoso) y si está entre eso y los gotos, definitivamente preferiría los gotos. Sin embargo, escribir funciones para estos casos es sin duda la mejor manera de hacerlo. – stinky472

+1

@KevinK - Gotos puede tener usos válidos en teoría, pero son extremadamente raros en la práctica. Argumentaría que si parece que tienes que usar un goto, la situación al menos merece un examen minucioso. Y para los desarrolladores principiantes, sugeriría evitarlos es una buena disciplina para aprender. – jwismar

4

Sí, como todos los demás dicen. C++ especifica/exige esto.

Pero sólo para añadir a esto, para lo completo: si su goto utiliza el computed- goto extensión se encuentra en algunos compiladores - gcc, sonido metálico, posiblemente otros, pero no incluyendo MSVC última supe - si o no el el destructor del objeto se llamará bastante confuso. Cuando un goto va a una única ubicación, está muy claro a qué destructores se debe llamar antes de la transferencia del flujo de control. Pero con un goto calculado, diferentes destructores podrían necesitar ser llamados dinámicamente, para dar la semántica "esperada". No estoy seguro de qué hacen los compiladores que implementan esta extensión, en esos casos. Mi memoria al encontrar esto es que el clang advierte cuando un goto calculado puede dejar un ámbito con un objeto con un destructor no trival, alegando que no se invocará el destructor. En algunos casos eso podría estar bien, en otros no. No sé de pasada qué hacen los demás compiladores. Solo tenga en cuenta el problema si desea usar gotos computados en concierto con objetos con destructores no triviales.

+0

Gracias. Solo uso gotos computados de C y en situaciones muy raras. –

Cuestiones relacionadas