Double Possible:
Le fait d'utiliser desgoto
de fuite de variables?Dans l'exemple suivant, lorsque l'
goto
est appelé à aller "à l'envers", le destructeur d'A
est appelé. Pourquoi est-il comme ça? Objeta
n'est pas en laissant son champ d'application, est-il? La norme dit rien à propos de ce comportement concernant l'goto
?void f() { start: A a; goto start; }
Réponses
Trop de publicités?6.6 Sauter consolidés (stmt.saut]
Paragraphe 2:
Lors de la sortie du champ d'application (cependant accompli), les objets automatique de la durée de stockage (3.7.3) qui ont été construits dans cette étendue sont détruits dans l'ordre inverse de leur construction. [ Note: Pour les temporaires, voir 12.2. -fin de la remarque] le Transfert de sortir d'une boucle, d'un bloc, ou dos passé un initialisé la variable automatique de la durée de stockage implique la destruction d'objets automatique de la durée de stockage qui sont dans la portée au point transférés à partir, mais pas au point de transféré à. (Voir 6.7 pour les transferts en blocs). [Note: Toutefois, le programme peut être interrompu (par appel à std::exit() ou std::abort() (18.5), par exemple), sans détruire les objets de la classe automatique de la durée de stockage. - la note de fin ]
Je pense que l'important est:
ou dos passé un initialisé la variable automatique de la durée de stockage implique la destruction
La durée de vie de l'objet a
commence à partir de sa déclaration, et s'étend jusqu'à la fin du bloc contenant.
Cela signifie que, en revenir à l'avant de la déclaration, vous sauter à un cadre de pile situations où le local n'existe pas, donc il doit être détruite
L'
point of declaration
pour un nom est immédiatement après sa complète de demande de déclaration (article 8) et avant son initialiseur (le cas échéant) , [...] (§ 3.3.2)Un nom déclaré dans un bloc (6.3) est locales à ce bloc; il a le bloc de portée. Son champ d'application potentiel commence à sa point de la déclaration (3.3.2) et se termine à la fin de son bloc. Une variable déclarée dans le bloc de portée est locale variable. (§ 3.3.3)
Voici une citation de la norme. Il inclut même un exemple qui est presque identique à la vôtre:
C++11 6.7 Déclaration [stmt.dcl]
2 Variables automatique de la durée de stockage (3.7.3) sont initialisés à chaque fois leur déclaration-déclaration est exécutée. Les Variables automatique de la durée de conservation déclarée dans le bloc sont détruits à la sortie de l' bloc (6.6).
3 Il est possible de transférer en un bloc, mais pas d'une manière qui contourne les déclarations à l'initialisation. Un programme de sauts à partir d'un point où une variable automatique de la durée de stockage n'est pas dans le champ d'application à un point où il est dans la portée est mal formé, à moins que la variable est de type scalaire, le type de classe avec un trivial par défaut constructeur et d'un trivial destructeur, un cv qualifiés version de l'un de ces types, ou un tableau de l'un des types précédents et est déclarée sans un initialiseur (8.5). [ Exemple:
void f() {
// ...
goto lx; // ill-formed: jump into scope of a
// ...
ly:
X a = 1;
// ...
lx:
goto ly; // OK, jump implies destructor
// call for a followed by construction
// again immediately following label ly
}
fin de l'exemple ]
Comme expliqué dans l'exemple, l' goto
implique la destruction. La déclaration-déclaration (A a;
dans votre code) signifie que le constructeur est ré-exécuté après chaque saut.
Autrement dit, start:
est une étiquette et déclare une portée [nother]
En supposant que start
est comme <0x00003000>
, A a sera à <0x00003000> + some_offset
disons <0x00003004>
.
goto start
demandera au PC (compteur de programmes) d'aller à l'adresse de début qui se produit avant la déclaration de A - en dehors de sa portée - d'où " destroy a
" appelle le destructeur .