gpt4 book ai didi

c++ - 跳转表/分支与取消引用函数指针是一回事吗?

转载 作者:太空宇宙 更新时间:2023-11-04 00:59:40 24 4
gpt4 key购买 nike

我一直在努力了解跳转表到底是什么,但我在理解某些东西时遇到了困难。从我见过的许多例子来看,它们似乎都可以归结为这个,或者至少这是它的一个版本:

void func1() {};
void func2() {};
void func3() {};

int main()
{
void(*jumpTo[3])(void) = { func1, func2, func3 };
jumpTo[1]();

return 0;
}

这些看起来只是一个函数指针数组,由某个值/位置索引。那么跳转表是否只是索引一个函数指针数组呢?我对此很好奇,因为我看到很多人说 switch 语句经常被编译成跳转表作为一种性能衡量标准。据我了解,通过以这种方式跳转到函数,它涉及指针解引用和函数调用。我认为这两者都不是很好的性能。

该网站上的另一个回答说,通过这种方式“您将添加 switch 语句不一定具有的函数调用开销。”编译为跳转表的开关如何避免函数调用?

此外,这里有一个获得高票数的答案说“跳转表可以是指向函数的指针数组,也可以是机器代码跳转指令数组。”您将如何跳转到机器代码指令而不是取消引用指针?这样更快吗?

两者之间的区别是在我上面的示例中,指针不必取消引用,因为它可以静态绑定(bind)吗?与在运行时传入随机数作为索引相反?

谢谢。

最佳答案

跳转表和你的函数表基本上是一样的——一个地址数组。跳转表包含 goto - 目标的地址。两者之间的唯一区别是跳跃的方式。当一个函数被调用时,返回地址被压入堆栈,因此当函数终止时它可以返回。

这里是一个跳转表的例子:

#include <stdio.h>
int main(int argc, char *argv[])
{
switch (argc)
{
case 1:
printf("You provided no arguments.");
break;
case 2:
printf("You provided one argument.");
break;
case 3:
printf("You provided two arguments.");
break;
case 4:
printf("You provided three arguments.");
break;
case 5:
printf("You provided four arguments.");
break;
case 6:
printf("You provided five arguments.");
break;
default:
printf("You provided %d arguments.", argc-1);
break;
}
return 0;
}

编译为:

    cmp edi, 6 ;Bounds check
ja .L2 ;jump to default branch
mov eax, edi
jmp [QWORD PTR .L4[0+rax*8]]
.L4:
.quad .L2 ;case 0 (same as default!!!)
.quad .L3 ;case 1
.quad .L5 ;case 2
.quad .L6 ;case 3
.quad .L7 ;case 4
.quad .L8 ;case 5
.quad .L9 ;case 6

关于c++ - 跳转表/分支与取消引用函数指针是一回事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45253712/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com