Sar*_*adi 24 c c++ gcc goto language-lawyer
我正在玩标签作为值,并最终得到这个代码.
int foo = 0;
goto *foo;
Run Code Online (Sandbox Code Playgroud)
我的C/C++经验告诉我*foo
手段dereference foo
,这不会编译因为foo
不是指针.但它确实编译.这实际上是做什么的?
gcc (Ubuntu 4.9.2-0ubuntu1~12.04) 4.9.2
,如果重要的话.
Kei*_*son 24
这是gcc中的已知错误.
gcc有一个记录的扩展,允许声明表单
goto *ptr;
Run Code Online (Sandbox Code Playgroud)
哪里ptr
可以是任何类型的表达式void*
.作为此扩展的一部分,将一元&&
应用于标签名称会生成标签的类型地址void*
.
在你的例子中:
int foo = 0;
goto *foo;
Run Code Online (Sandbox Code Playgroud)
foo
显然是类型int
,而不是类型void*
.一个int
值可以转换到void*
,但只有有明确的转换(除了一个空指针常数,在这里不适用的特殊情况).
表达式*foo
本身被正确诊断为错误.还有这个:
goto *42;
Run Code Online (Sandbox Code Playgroud)
编译没有错误(42
如果我正确读取汇编代码,生成的机器代码似乎是跳转到地址).
一个快速实验表明gcc生成相同的汇编代码
goto *42;
Run Code Online (Sandbox Code Playgroud)
就像它一样
goto *(void*)42;
Run Code Online (Sandbox Code Playgroud)
后者是对文档扩展的正确使用,如果由于某种原因,你想要跳转到地址42,那么你可能应该这样做.
我已经提交了一份错误报告 - 该报告很快被关闭,作为2007年提交的此错误报告的副本.
似乎是一个GCC错误.这是一个clang输出作为比较.看来这些是我们应该期待的错误.
$ cc -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
$ cc goto.c
goto.c:5:7: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'const void *' [-Wint-conversion]
goto *foo;
^~~~
goto.c:5:2: error: indirect goto in function with no address-of-label expressions
goto *foo;
^
1 warning and 1 error generated.
Run Code Online (Sandbox Code Playgroud)
goto.c
源代码:
int main(int argc, char const *argv[])
{
int foo = 0;
goto *foo;
}
Run Code Online (Sandbox Code Playgroud)