`((void(*)())0x1000)();`是什么意思?

时间:2015-05-20 09:20:35

标签: c pointers void

这是一个代码,目的是将程序计数器设置为跳转到地址0x1000。我知道它做了什么,但我不明白怎么做。这与我缺乏C语言知识有关。可能你可以赐教。这是声明/功能(我甚至不知道它是什么:))

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

我认为它是指向返回void并且不接受任何参数的函数的指针。如果我错了,请纠正我。

4 个答案:

答案 0 :(得分:44)

C声明使用一个简单的规则从内到外解码:从标识符开始并在右侧检查[](数组)或()(函数)然后检查左侧为值的类型(存储在数组中或由函数返回),不包括括号;从括号中逃脱并重复。

例如:

void (*p)()

p是(右边没有)一个指针(在左边,不要越过括号)(转义括号,读取下一级)一个函数(右),什么都不返回(左)。

当缺少标识符(在这种情况下为p)时,剩下的只是一个类型声明。

括在括号中的类型,放在值前面是一个类型转换。

(void (*)())0x1000

将数字0x1000转换为指向不返回任何内容的函数的指针(请参阅上面关于p声明的段落中括号内的内容)

在下一个级别,上面的表达式(指向函数的指针可以与函数名称一样使用)用于执行指向的代码。

见下面整个表达式:

(
  (
    void (*)()   /* type: pointer to function that doesn't return anything     */
  )0x1000        /* value 0x1000 treated as a value of the type declared above */
)                /* enclose in parentheses to specify the order of evaluation  */ 
();              /* the pointer above used as a function name to run the code  */

答案 1 :(得分:17)

(void (*)())是一个指向函数的指针,该函数返回void并获取一个未指定但固定的参数。

(void (*)())0x1000 将文字0x1000投射到上述类型。

最后,后缀() 调用该函数。前面的表达式需要在括号中,否则后缀()将绑定到0x1000,这在语法上无效。

由你来检查演员是否真的有效。如果没有,那么程序的行为是 undefined

答案 2 :(得分:13)

常数

0x1000

被转换为类型:

(type)0x1000

类型是void (*)() - 函数的指针(星号),它不带参数(右边是空括号)(oops,见the comment by pmg)并且不返回任何值({{1} } 在左边)。星号上的其他数据阻止将其与void相关联,这会在此处错误地创建void类型。

所以在演员表之后你有一个指向无参数0x1000的无参数void函数的指针:

void *

那个功能......

(void (*)())0x1000
通过添加空参数列表来调用

((void (*)())0x1000)

答案 3 :(得分:6)

编写该代码的人应该以可读的方式重写它:

#define ADDRESS_OF_FUNCTION_X 0x1000

typedef void (*func_ptr_t)(void);

...

func_ptr_t function_x = (func_ptr_t)ADDRESS_OF_FUNCTION_X;
function_x();

代码的作用现在几乎都是自我记录的。