强制进行另一轮 C 宏扩展的其他方法?

Other ways to force another round of C macro expansion?

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

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

示例 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

当通过 gcc -E test.h 通过预处理器保存到文件 (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_ 宏的情况下也能工作,并且与您似乎想要的相差不远。