((void(*)(void))0)();
因此我们对这个棘手的类型(void(*))(void)
进行整数0类型转换然后执行它。 Source声称这应该有效,但它实际上是什么?
我猜想,这必须是像#define TRUE FALSE
这样的C笑话之一。
答案 0 :(得分:24)
这是一个期望没有参数并且不返回任何值的函数:
void f(void)
这是一个指向函数的指针,该函数期望没有参数并且不返回任何值:
void (*p)(void)
这是该指针的类型:
void (*)(void) /* just remove the p! */
这是括号中的类型:
(void (*)(void))
这是对该类型的强制转换(括号中的类型,后跟一个值):
(void (*)(void))0
还在我身边吗?到目前为止,我们有一个整数值0强制转换为指向函数的指针 - 不带参数 - 并且不返回任何内容。
强制转换是一个带指针到函数类型的表达式。如果您有其中一个,可以这样称呼它:
(your expression here)(arguments to the function)
第一组括号仅用于优先级,有时可能不需要(但这次它们是)。最终结果:
((void (*)(void))0)(/* no args */);
取值0,将其转换为指向函数的指针 - 期望 - 无参数 - 并且不返回任何内容,并调用它,不提供任何参数。
答案 1 :(得分:14)
将地址强制转换为函数指针然后调用它的语法 看起来像这样:
((void (*)(void))address)();
虽然这样做可能更清楚:
void (*fptr)(void) = (void (*)(void))address;
fptr();
表示((void(*)(void))0)();
指令通常用于在固件中跳转到0。这有点不合适,因为它实际上调用0而不是跳到0,但实际上它不会有任何区别(将执行fw热启动)
答案 2 :(得分:9)
这会将NULL
视为一个函数指针并执行它,它应该在大多数系统上引发一个sigbus或类似的东西。
void(*)(void) <- type, function pointer taking no arguments and returning no value
(void(*)(void)) <- cast to above type
((...)0) <- cast NULL/0 to said type
((...)0)() <- execute the cast value as a function
答案 3 :(得分:3)
在某些嵌入式系统(例如AVR微控制器)上,这可能是一种向复位向量实现跳转(实际上是一次调用)的方法。
您可以通过这种方式重启SW,尤其是在此之前已禁用中断的情况下。
答案 4 :(得分:3)
AVR通常会在地址0加载用户应用程序。一个加载到更高地址的引导加载程序可能跳转到(调用函数at)地址0.所以,转换和调用在这种环境中,0地址是一个有用的结构。