我正在玩标签作为值 https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html并最终得到这段代码。
int foo = 0;
goto *foo;
我的 C/C++ 经验告诉我*foo
means dereference foo
这不会编译,因为foo
不是指针。但它确实可以编译。这实际上有什么作用?
gcc (Ubuntu 4.9.2-0ubuntu1~12.04) 4.9.2
,如果重要的话。
这是 gcc 中的一个已知错误。
海湾合作委员会有一个记录扩展 https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Labels-as-Values.html允许以下形式的声明
goto *ptr;
where ptr
可以是任何类型的表达式void*
。作为此扩展的一部分,应用一元&&
标签名称产生标签的地址,类型为void*
.
在你的例子中:
int foo = 0;
goto *foo;
foo
显然是类型int
,不是类型void*
. An int
值可以转换为void*
,但仅限于显式强制转换(空指针常量的特殊情况除外,此处不适用)。
表达方式*foo
其本身被正确诊断为错误。和这个:
goto *42;
编译没有错误(生成的机器代码似乎是跳转到地址42
,如果我正确地阅读了汇编代码)。
快速实验表明 gcc 生成相同的汇编代码
goto *42;
正如它所做的那样
goto *(void*)42;
后者是对已记录扩展的正确使用,如果出于某种原因您想跳转到地址 42,则可能应该这样做。
我已经提交了一份错误报告 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69704——作为复制品很快就被关闭了这个错误报告 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=32122,2007 年提交。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)