还有其他方法来强制另一轮C宏扩展吗?



我有一个C宏库,通过定义_(…)以一种不引人注目的方式注入错误处理。我想用一个函数(实际上是一个宏)扩展库,它包含了一些额外的复杂性,但仍然可以与错误处理注入宏一起使用……但这似乎不起作用,因为我遇到了嵌套/递归宏扩展的问题。

我通过写一个"妥协"来解决这个问题。宏来强制我需要的额外级别的宏展开,但它不是完美的,因为它偏离了注入错误处理的通常语法(参见下面示例代码的最后一行)。

示例C代码:

#define _(...) (__VA_ARGS__); check_and_handle_errno()
#define DO(x, ...) (x ? do_impl(static_arg, __VA_ARGS__) : NULL)
#define DO_(x, ...) _(x ? do_impl(static_arg, __VA_ARGS__) : NULL)
type * name = do_impl(static_arg, arg2);  // no error handling
type * name = do_impl _(static_arg, arg2);  // with error handling
// a bit more complex
type * name = (arg1 ? do_impl(static_arg, arg2) : NULL);  // no error handling
type * name = _(arg1 ? do_impl(static_arg, arg2) : NULL);  // with error handling
// complexity wrapped by macro
type * name = DO(arg1, arg2);  // no error handling
type * name = DO _(arg1, arg2);  // with error handling, but doesn't fully expand
type * name = DO_(arg1, arg2);  // compromise, but I really want the syntax above

保存到文件(test.h)并通过gcc -E test.h通过预处理器运行时,示例被转换为以下内容:

type * name = do_impl(static_arg, arg2);
type * name = do_impl (static_arg, arg2); check_and_handle_errno();
type * name = (arg1 ? do_impl(static_arg, arg2) : NULL);
type * name = (arg1 ? do_impl(static_arg, arg2) : NULL); check_and_handle_errno();
type * name = (arg1 ? do_impl(static_arg, arg2) : NULL);
type * name = DO (arg1, arg2); check_and_handle_errno();
type * name = (arg1 ? do_impl(static_arg, arg2) : NULL); check_and_handle_errno();

有没有人知道如何在示例代码的第二到最后一行实现语法(并将其扩展到示例中的最后一行)?

谢谢!

我不确定您想要的语法是否可行,它似乎不可行-但从逻辑上讲,您要完成的内容相当于:

type * name = _(DO(arg1, arg2));

即如果arg1为真,先执行arg2,然后检查错误。

这可以在没有第三个DO_宏的情况下工作,并且与您似乎想要的相差不远。

最新更新