这是一个代码,目的是将程序计数器设置为跳转到地址0x1000
。我知道它做了什么,但我不明白怎么做。这与我缺乏C语言知识有关。可能你可以赐教。这是声明/功能(我甚至不知道它是什么:))
((void (*)())0x1000)();
我认为它是指向返回void
并且不接受任何参数的函数的指针。如果我错了,请纠正我。
答案 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();
代码的作用现在几乎都是自我记录的。