I was playing around with labels as values and ended up with this code.
int foo = 0; goto *foo;
My C/C++ experience tells me *foo
means dereference foo
and that this won't compile because foo
isn't a pointer. But it does compile. What does this actually do?
gcc (Ubuntu 4.9.2-0ubuntu1~12.04) 4.9.2
, if important.
This is a known bug in gcc.
gcc has a documented extension that permits a statement of the form
goto *ptr;
where ptr
can be any expression of type void*
. As part of this extension, applying a unary &&
to a label name yields the address of the label, of type void*
.
In your example:
int foo = 0; goto *foo;
foo
clearly is of type int
, not of type void*
. An int
value can be converted to void*
, but only with an explicit cast (except in the special case of a null pointer constant, which does not apply here).
The expression *foo
by itself is correctly diagnosed as an error. And this:
goto *42;
compiles without error (the generated machine code appears to be a jump to address 42
, if I'm reading the assembly code correctly).
A quick experiment indicates that gcc generates the same assembly code for
goto *42;
as it does for
goto *(void*)42;
The latter is a correct use of the documented extension, and it's what you should probably if, for some reason, you want to jump to address 42.
I've submitted a bug report -- which was quickly closed as a duplicate of this bug report, submitted in 2007.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With