强制进行另一轮 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_
宏的情况下也能工作,并且与您似乎想要的相差不远。
我有一个 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_
宏的情况下也能工作,并且与您似乎想要的相差不远。