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