gpt4 book ai didi

c - "Local"C 中的标签和跳转表实现

转载 作者:行者123 更新时间:2023-12-04 23:11:43 24 4
gpt4 key购买 nike

我正在尝试用 C 制作一个基于宏的跳转表。

下面是一些示例代码:

#include "stdio.h"

#define GOTO(X) static void* caseArg[] = {&&I0, &&R0, &&S0, &&F0, &&G0, &&H0}; \
goto *caseArg[X];

#define FINISH() goto caseEnd;

int main(int argc, char** argv) {

GOTO(1);

I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in R0\n"); FINISH();
F0: printf("in R0\n"); FINISH();
G0: printf("in R0\n"); FINISH();
H0: printf("in R0\n"); FINISH();

caseEnd:;

}

可能的标签(I0、R0 等)必须相同。

问题是:我希望能够在同一源文件的不同作用域部分使用相同的宏。但是,编译器提示标签已定义。

我想要达到的目标:
int main(int argc, char** argv) {

{ // scope 1

GOTO(1);

I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in R0\n"); FINISH();
F0: printf("in R0\n"); FINISH();
G0: printf("in R0\n"); FINISH();
H0: printf("in R0\n"); FINISH();

caseEnd:;

}

{ // scope 2

GOTO(4);

I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in R0\n"); FINISH();
F0: printf("in R0\n"); FINISH();
G0: printf("in R0\n"); FINISH();
H0: printf("in R0\n"); FINISH();

caseEnd:;

}

}

有任何想法吗?任何可能的解决方法?

最佳答案

您需要 __label__扩展(至少在 gcc、clang 和 tinycc 中),它允许您将标签范围限定到一个块。

标签需要在块的最开始用

__label__ I0, R0, S0, F0, G0, H0;

(连续 __label__ I0; __label__ R0; ... 或两种形式的混合也适用。)。

除非用 __label__ 声明局部作用域, C 标签的范围仅限于它们的封闭函数。

你的例子 __label__ :
#include "stdio.h"

#define GOTO(X) static void* const caseArg[] = {&&I0, &&R0, &&S0, &&F0, &&G0, &&H0}; \
goto *caseArg[X];

#define FINISH() goto caseEnd;

#define DECL_LBLS() __label__ I0, R0, S0, F0, G0, H0, caseEnd

int main(int argc, char** argv) {

{ DECL_LBLS();

GOTO(2);

I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in S0\n"); FINISH();
F0: printf("in F0\n"); FINISH();
G0: printf("in G0\n"); FINISH();
H0: printf("in H0\n"); FINISH();
caseEnd:;
}

{ DECL_LBLS();

GOTO(1);

I0: printf("in I0\n"); FINISH();
R0: printf("in R0\n"); FINISH();
S0: printf("in S0\n"); FINISH();
F0: printf("in F0\n"); FINISH();
G0: printf("in G0\n"); FINISH();
H0: printf("in H0\n"); FINISH();
caseEnd:;
}
}

https://gcc.godbolt.org/z/63YSkG

在这种特殊情况下,这种基于本地标签的跳台似乎比普通的旧 switch 便宜。 .

关于c - "Local"C 中的标签和跳转表实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59844434/

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