2010-07-05 31 views
37

Consultez le code suivant:Sortez d'un pâté de maisons: les destructeurs sont-ils appelés?

void foo() 
{ 
    { 
     CSomeClass bar; 

     // Some code here... 

     goto label; 

     // and here... 
    } 

label: 
    // and here... 
} 

Est-ce que l'destructor de bar appelé?

+0

Pourquoi avez-vous besoin de le savoir? 'goto' a du sens dans le code généré, mais là vous pouvez et devriez éviter les objets avec des destructeurs de toute façon. – MSalters

+13

@MSalters: cela ne fait rien du tout, pourquoi devriez-vous éviter les objets avec des destructeurs? –

+1

@Viktor: Permettez-moi de développer la deuxième partie de la phrase: _In code_ généré, vous pouvez et devriez éviter les objets avec des destructeurs de toute façon. L'utilisation canonique de 'goto' est dans le code FSM généré. Ici, les sauts se produisent en arrière et en avant, sans tenir compte des états de code d'état qui se trouvent juste au milieu. Les états FSM ne sont tout simplement pas linéaires, mais le code C++ doit l'être. – MSalters

Répondre

52

La norme C++ dit:

la sortie d'un champ (mais accompli), destructeurs (12,4) sont a appelé à tous les objets construits avec la durée de stockage automatique (3.7.2) (nom o bjects ou temporaires) qui sont déclarées dans cette portée, dans l'ordre inverse de leur déclaration .

Donc la réponse est "oui".

+0

Merci. C'est ce dont j'avais besoin. –

9

1) Oui. 2) Ne faites pas cela.

Elaboration: conceptuellement, ce n'est pas différent de laisser une boucle via un break. goto, cependant, est fortement, fortement découragé. Il n'est presque jamais nécessaire d'utiliser goto, et toute utilisation devrait être examinée pour savoir ce qui se passe.

+0

Réponse parfaite. – Mizipzor

+1

2) vous faites cela lorsque vous échappez aux boucles. –

+14

En fait, goto a du sens dans un certain nombre de circonstances. –

21

Oui, ils seront appelés.

Mise à jour: (.. Il est correct de faire cela, GOTO est pas pire que de jeter des exceptions factices ou en utilisant Bools/ifs pour sortir des choses Un simple goto dans une fonction ne permet pas le code spaghetti)

+7

+ 1 pour contredire l'élève égoïste qui a ressenti le besoin de baisser la garde parce qu'il pense personnellement que les gotos sont mauvais. Gotos ont des utilisations valables, des gens, indépendamment de ce que vos professeurs vous ont dit. – KevenK

+2

"c'est bien de faire ça, gotos n'est pas pire que de lancer des fausses exceptions ou d'utiliser bools/ifs pour sortir des choses" Lancer une exception fictive est une façon terrible de le faire (lancer des exceptions est généralement très cher) ça et gotos, je préférerais certainement gotos. Cependant, écrire des fonctions pour ces cas est certainement la meilleure voie à suivre. – stinky472

+1

@KevinK - Gotos peut avoir des utilisations valables en théorie, mais elles sont extrêmement rares en pratique. Je dirais que s'il semble que vous deviez utiliser un goto, la situation mérite au moins un examen attentif. Et pour les débutants, je suggérerais de les éviter, c'est une bonne discipline à apprendre. – jwismar

4

Oui, comme tout le monde le dit. C++ spécifie/impose ceci.

Mais pour ajouter à cela, pour être complet: si votre goto utilise l'extension goto computed- trouvé dans certains compilateurs - gcc, clang, peut-être d'autres, mais pas y compris MSVC dernier, je savais - que ce soit ou non destructeur de l'objet sera appelé est assez brumeux. Quand un goto va à un seul endroit, il est très clair quels destructeurs doivent être appelés avant le transfert de contrôle-débit. Mais avec un goto calculé, différents destructeurs peuvent être appelés dynamiquement, pour donner la sémantique "attendue". Je ne suis pas sûr de savoir ce que font les compilateurs qui implémentent cette extension, dans ces cas-là. Ma mémoire de rencontrer ceci est que clang avertit quand un goto calculé pourrait laisser une portée avec un objet avec un destructeur non trival, affirmant que le destructeur ne sera pas appelé. Dans certains cas, cela pourrait être bien, dans d'autres pas. Je ne sais pas ce que font les autres compilateurs. Juste être au courant du problème si vous voulez utiliser goto s de concert avec des objets avec des destructeurs non trivial.

+0

Merci. Je n'utilise que des gotos calculés de C, et dans des situations très rares. –