I bumped against this error in some code, and after some experimenting I stumbled upon this weirdness - I get it for std::string
, but not for int
.
For std::string
I get error C2362: initialization of 'unused' is skipped by 'goto label'
:
{ goto label;
std::string unused;
label:;
}
For int
I don't get any error, however:
{ goto label;
int unused = 10;
label:;
}
Why the difference? Is it because std::string
has a non-trivial destructor?
This is covered in the draft C++ standard section 6.7
Declaration statement which says (emphasis mine):
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps87 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).
and provides the following 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
}
Although both cases should generate an error since your are bypassing an initialization in both cases, this however would have been fine:
goto label;
int unused ;
label:
So Visual Studio
is not correct here, both gcc
and clang
generate and error for this code, gcc
says:
error: crosses initialization of 'int unused'
int unused = 10;
^
Of course Visual Studio
can have extension like that as long as they document it but it is not portable to use such an extension, as I pointed out both clang
and gcc
generate an error for this.
We can find a rationale for why we don't want to jump across an initialization in defect report 467 which sought to have the same restriction added for local static variable (it was rejected):
[...]automatic variables, if not explicitly initialized, can have indeterminate (“garbage”) values, including trap representations, [...]