Here is a relevant quote from the standard. It even includes an example that is almost identical to yours:
C++11 6.7 Declaration statement [stmt.dcl]
2 Variables with automatic storage duration (3.7.3) are initialized each time their declaration-statement is
executed. Variables with automatic storage duration declared in the block are destroyed on exit from the
block (6.6).
3 It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A
program that jumps from a point where a variable with automatic storage duration is not in scope to a
point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default
constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the
preceding types and is declared without an initializer (8.5). [ Example:
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
}
—end example ]
As explained in the example, the goto
implies destruction. The declaration-statement (A a;
in your code) means the constructor is re-executed after each jump.