Reputation: 3503
Case 1
This was based on another question of mine posted yesterday, that I accepted, although reluctantly, which can be summarized by the following code :
{
...
goto Label;
A a;
...
Label:DoSomething();
}
where A
is any class with a defined constructor
and a default destructor
. DoSomething()
doesn't use a
. From my understanding (I'm still struggling with C++ basic constructs) A
's destructor would not be called in this situation, since the object a
was not even constructed.
Note that the VS2008 compiler gives you a warning (C4533 : initialization of 'a' is skipped by 'goto Label'
) not an error, unless you try to define a destructor
for A
, when the compiler, mysteriously, changes the warning into an error (C2362 : initialization of 'a' is skipped by 'goto Label'
), as if to block someone to probe into the problem, which by the way, reminded me of a quantum phenomenon in nature.
Case 2
This is the normal occurrence of a constructor
throwing an exception, in which case the destructor
is not called, as discussed here and here.
Therefore
In Case1 the constructor
is not invoked, but the destructor
is called to destroy something that was not created, which seems odd to me. In Case2 the constructor is called, throws an exception and the destructor
is not invoked, which seems reasonable to me.
I believe these two examples deserve further clarification.
Edit
In Case2 the compiler probably uses flags to avoid destroying objects which were not constructed because of a throw. Why can't those same flags be used in Case1 to identify the objects which were not constructed because of a goto
?
Upvotes: 0
Views: 272
Reputation: 36049
In C++, gotos across variable initializations (constructor calls) are forbidden exactly for this reason: The goto skips the constructor call. After the goto and the call to DoSomething, the variable a
would go out of scope, so the destructor would be called on a
, which has not been constructed because the goto skipped the constructor call.
VS2008 is lenient here and allows a violation of the standard when an auto-generated destructor, probably on a POD, has no effect.
Upvotes: 4
Reputation: 19721
Actually case 1 is invalid C++. The compiler has to issue a diagnostic for this and is allowed to not compile that at all. If the compiler compiles it anyway, it's completely up to the compiler what to do with it. It would be sensible to not destruct the object in that case, however that requires extra machinery, and that means unneeded overhead for correct programs (the program needs to check an internal flag whether the object has been constructed). I don't think it could always be resolved at compile time whether that check is needed because that would likely be equivalent to the halting problem.
Upvotes: 3