什么是C表达式((void(*)(void))0)();意思?

时间:2013-12-03 16:56:01

标签: c

((void(*)(void))0)();

因此我们对这个棘手的类型(void(*))(void)进行整数0类型转换然后执行它。 Source声称这应该有效,但它实际上是什么?

我猜想,这必须是像#define TRUE FALSE这样的C笑话之一。

5 个答案:

答案 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地址是一个有用的结构。