gpt4 book ai didi

我可以创建一个有条件的 `goto` s 并用作表达式的宏吗?

转载 作者:行者123 更新时间:2023-12-05 06:26:45 26 4
gpt4 key购买 nike

是否可以创建一个扩展以下代码的宏

int error = 0;
struct parse_tree res = CLEANUP_parse(file_hdl);
// ...
cleanup:
return error

在语义上等同于(足够)

int error = 0;
struct parse_tree res;
struct parse_tree tmp = parse(file_hdl);
if(global_error_variable != 0) {
error = global_error_variable;
goto cleanup;
} else {
res = tmp;
}
// ...
cleanup:
return error

我担心它不可能的原因是 goto label; 是一个语句,我真的需要一个表达式。例如。像

#define CLEANUP_parse(file_hdl) ((tmp=parse(file_hdl)) ^ tmp ^ global_error_variable) ? goto cleanup : tmp

因为这个原因不起作用(并且因为 tmp 没有声明,可能更多)。

遗憾的是,编译器扩展只有在 GCC、VSC Texas Instrument 的 C 编译器支持它们时才有可能。

背景

我们有一个现有的代码库,其中每个函数返回一个整数错误代码,调用者跳转到 cleanup: 非零返回代码。我考虑引入使用全局错误代码来启用其返回值的函数,但希望以安全和向后兼容的方式进行。 The full picture on SE Code Review

最佳答案

Can I create a macro which conditionally gotos and serves as an expression?

不是一个表达式。考虑一种不同的方法,它只需要轻微的重构,但将与标准 C 兼容:

int error = 0;
struct parse_tree res;
CLEANUP_PARSE(res, file_hdl, error, cleanup);
// ...
cleanup:
return error;

那么你会:

#define CLEANUP_PARSE(res, file_hdl, error, cleanup) \
do { \
res = parse(file_hdl); \
if (global_error_variable != 0) { \
error = global_error_variable; \
goto cleanup; \
} \
} while(0)

当 GNU 扩展没问题时,您还可以添加带有语句表达式的 GNU 版本:

#ifdef __GNUC__
// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs
#define CLEANUP_PARSE_RET(file_hdl, ...) \
__extension__({ \
struct parse_tree _res; \
/* macro from above */ \
CLEANUP_PARSE(_res, file_hdl, __VA_ARGS__); \
_res; \
})
#endif

可以按您的预期使用:

struct parse_tree res = CLEANUP_PARSE_RET(file_hdl, error, cleanup);

并且库的用户可以选择他想要的版本,这取决于用户打算支持的编译器。

关于我可以创建一个有条件的 `goto` s 并用作表达式的宏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55745172/

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