Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'goto *foo' where foo is not a pointer. What is this?

Tags:

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.

like image 849
Sarvadi Avatar asked Feb 06 '16 02:02

Sarvadi


1 Answers

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.

like image 177
Keith Thompson Avatar answered Sep 25 '22 07:09

Keith Thompson