我正在玩标签作为值 ,最后得到这个代码。
int foo = 0; goto *foo;
我的C / C ++经验告诉我*foo
意味着dereference foo
并且这不会编译因为foo
不是指针。 但它确实编译。 这实际上是做什么的?
gcc (Ubuntu 4.9.2-0ubuntu1~12.04) 4.9.2
,如果重要的话。
这是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年提交的此错误报告的副本。
似乎是一个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.
goto.c
源代码:
int main(int argc, char const *argv[]) { int foo = 0; goto *foo; }
这不是错误,而是GCC标签和值扩展的结果 。 我猜他们有快速跳转表和JIT的想法。 使用此(错误)function,您可以跳转到function
// c goto *(int *)exit; // c++ goto *reinterpret_cast(std::exit);
并做一些非常有品味的事情,比如跳进一个字符串文字
goto *&"xe8r Hello, World!Yj1[jrZj4Xxcdx80,fxcdx80";
在线尝试!
不要忘记允许指针算术!
goto *(24*(a==1)+"xe87 Hello, Yj1[j7Zj4Xxcdx80xe86 World!Yj1[j6Zj4Xxcdx80,5xcdx80");
我会给读者留下额外的后果作为练习( argv[0]
, __FILE__
__DATE__
__FILE__
, __DATE__
等等)
请注意,您需要确保对跳转到的内存区域具有可执行权限。
需要了解更多c/c++开发分享‘goto * foo’其中foo不是指针。 这是什么?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享‘goto * foo’其中foo不是指针。 这是什么?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/980103.html