typedef void(*FUNC)(void);
int main(void)
{
//intptr_t m;
const static unsigned char insn[4] = { 0xff, 0xff, 0xff, 0xff };
FUNC function = (FUNC) insn;
function();
}
上面的代码给出了输出作为非法指令。有人可以解释原因吗? 。是因为函数指针没有函数的地址(因为它有一个数组的地址,它不能跳转到地址)
答案 0 :(得分:1)
由于指向数组第一个元素的指针不是指向函数的指针,因此通过变量function
调用“函数”来调用未定义的行为。当您调用未定义的行为时,任何事情都可能发生。非法指令的崩溃是完全合法的;所以擦掉磁盘上的所有数据。
根据标准,没有什么可以'预期'。正如评论中暗示的那样,可能发生的是存储在数组insn
中的堆栈中的字节(以及堆栈的其余部分,具有main()
的堆栈帧以及类似于参数列表和环境变量)将被视为机器代码。幸运的是,其中一个字节是无效(或非法)指令,程序停止。
答案 1 :(得分:0)
C11 J.5.7函数指针强制转换
1指向对象或
void
的指针可以转换为指向函数的指针,允许将数据作为函数调用(6.5.4)。2指向函数的指针可以强制转换为指向对象或
void
的指针,允许a 要检查或修改的功能(例如,通过调试器)(6.5.4)。
如果你只将数组名称转换为函数指针,那么你很好,但是你调用它是未定义的行为,因为它实际上并不是函数。
您可以尝试在数组中存储实际的函数指针地址,然后将其强制转换回函数指针并调用它们。但是,unsigned char
仍然无效,因为它太小,请改用uintptr_t
。