如何将goto标签存储在数组中然后跳转到它们?

18 c c++ goto jump-table

我想声明一个"jumplabels"数组.

然后我想跳到这个数组中的"jumplabel".

但我不知道该怎么做.

它应该类似于以下代码:

function()
{
    "gotolabel" s[3];
    s[0] = s0;
    s[1] = s1;
    s[2] = s2;

    s0:
    ....
    goto s[v];

    s1:
    ....
    goto s[v];

    s2:
    ....
    goto s[v];
}
Run Code Online (Sandbox Code Playgroud)

有谁知道如何执行此操作?

qrd*_*rdl 40

GCC功能可以称为" 标签作为值 ".

void *s[3] = {&&s0, &&s1, &&s2};

if (n >= 0 && n <=2)
    goto *s[n];

s0:
...
s1:
...
s2:
...
Run Code Online (Sandbox Code Playgroud)

它只适用于GCC!

  • 啊啊 gcc,如果你也能在 Visual Studio 中就好了! (4认同)

laa*_*lto 17

goto 需要一个编译时标签.

从这个例子看,你似乎正在实现某种状态机.最常见的是,它们被实现为switch-case结构:

while (!finished) switch (state) {
  case s0:
  /* ... */
  state = newstate;
  break;

  /* ... */
}
Run Code Online (Sandbox Code Playgroud)

如果需要它更动态,请使用函数指针数组.


lis*_*ine 12

没有直接的方法来存储代码地址以跳转到C.如何使用开关.

#define jump(x)  do{ label=x; goto jump_target; }while(0)
int label=START;
jump_target:
switch(label)
{
    case START:
        /* ... */
    case LABEL_A:
        /* ... */
}
Run Code Online (Sandbox Code Playgroud)

您可以找到每个无堆栈解析器/状态机生成器生成的类似代码.这样的代码不容易遵循,所以除非它是生成代码或你的问题最容易被状态机描述,我建议不要这样做.


Rik*_*ood 8

你可以使用函数指针而不是goto吗?

这样你就可以创建一个函数数组来调用和调用适当的函数.

  • @youllknow:上面评论中的"我认为"这个词告诉我,你真的有可能因为"过早优化"而堕落.第一个目标应该是从一个明确的"工作"解决方案开始,然后根据需要进行优化.考虑一下:只有1个编译器将此功能作为扩展,但是,每个C/C++编译器都使用状态机.如果这是解决此问题的最佳方法,为什么不是每个编译器都有此功能? (7认同)
  • @youllknow:函数调用非常便宜:它不比goto贵得多,而且问题少得多.请记住,编译器总是比优化时更好. (2认同)
  • @youllknow:会有性能差异,但你需要记住"清晰度"和"性能"之间的权衡.如果是我,我的第一个"性能"调整是看到我可以使用模板+内联函数的某些组合,因此允许编译器尽可能地进行优化.顺便说一句,这可能已经存在于boost精神库中:http://www.boost.org/doc/libs/1_39_0/libs/statechart/doc/index.html. (2认同)

unw*_*ind 6

在简单的标准C中,据我所知,这是不可能的.然而,这里记录的GCC编译器中有一个扩展,这使得这成为可能.

扩展引入了new运算符&&,以获取标签的地址,然后可以与该goto语句一起使用.


Bas*_*ard 5

这就是switch陈述的内容.

switch (var)
{
case 0:
    /* ... */
    break;
case 1:
    /* ... */
    break;
default:
    /* ... */
    break;  /* not necessary here */
}
Run Code Online (Sandbox Code Playgroud)

请注意,它不一定由编译器转换为跳转表.

如果你真的想自己构建跳转表,可以使用函数指针数组.

  • @youllknow:通常好的编译器会为您优化密集切换到跳转表.所以不,开关不一定很慢. (3认同)