Suppose these code compiled in g++
:
#include <stdlib.h>
int main() {
int a =0;
goto exit;
int *b = NULL;
exit:
return 0;
}
g++
will throw errors:
goto_test.c:10:1: error: jump to label ‘exit’ [-fpermissive]
goto_test.c:6:10: error: from here [-fpermissive]
goto_test.c:8:10: error: crosses initialization of ‘int* b’
It seems like that the goto
can not cross pointer definition, but gcc
compiles them ok, nothing complained.
After fixed the error, we must declare all the pointers before any of the goto
statement, that is to say you must declare these pointers even though you do not need them at the present (and violation with some principles).
What the origin design consideration that g++
forbidden the useful tail-goto statement?
Update:
goto
can cross variable (any type of variable, not limited to pointer) declaration, but except those that got a initialize value. If we remove the NULL
assignment above, g++
keep silent now. So if you want to declare variables that between goto
-cross-area, do not initialize them (and still violate some principles).
Goto can't skip over initializations of variables, because the respective objects would not exist after the jump, since lifetime of object with non-trivial initialization starts when that initialization is executed:
C++11 §3.8/1:
C++11 §6.7/3:
Since the error mentions
[-fpermissive]
, you can turn it to warning by specifying that compiler flag. This indicates two things. That it used to be allowed (the variable would exist, but be uninitialized after the jump) and that gcc developers believe the specification forbids it.The compiler only checks whether the variable should be initialized, not whether it's used, otherwise the results would be rather inconsistent. But if you don't need the variable anymore, you can end it's lifetime yourself, making the "tail-goto" viable:
is perfectly valid.
On a side-note, the file has extension
.c
, which suggests it is C and not C++. If you compile it withgcc
instead ofg++
, the original version should compile, because C does not have that restriction (it only has the restriction for variable-length arrays—which don't exist in C++ at all).There is an easy work-around for those primitive types like
int
: