Ответ 1
Это известная ошибка в gcc.
gcc имеет документальное расширение, которое позволяет выписать форму
goto *ptr;
где ptr
может быть любым выражением типа void*
. Как часть этого расширения, применение унарного &&
к имени метки дает адрес метки, типа void*
.
В вашем примере:
int foo = 0;
goto *foo;
foo
явно имеет тип int
, а не тип void*
. Значение int
может быть преобразовано в void*
, но только с явным приведением (за исключением специального случая константы нулевого указателя, которая здесь не применяется).
Выражение *foo
само по себе правильно диагностируется как ошибка. И это:
goto *42;
компилируется без ошибок (сгенерированный машинный код выглядит как переход к адресу 42
, если я правильно читаю код сборки).
Быстрый эксперимент показывает, что gcc генерирует один и тот же код сборки для
goto *42;
как и для
goto *(void*)42;
Последнее является правильным использованием документированного расширения, и это то, что вам должно быть, если по какой-то причине вы хотите перейти к адресу 42.
Я отправил отчет об ошибке - который был быстро закрыт как дубликат этого отчета об ошибке, представленный в 2007 году.