C中的大小写可变参数宏

时间:2019-03-09 07:39:11

标签: c macros c11 variadic-macros

我有2个包装器宏,用于声明函数输入参数:

/**
 * @brief   An assert wrapper with no value return in case assert fails.
 * @param   x_: value to test for being non zero.
 */
#define UTIL_ASSERT_VOID(x_)                                                \
    assert_param(x_);                                                       \
    if (!x_)                                                                \
        return;                                                             \

/**
 * @brief   An assert wrapper with a value return in case assert fails.
 * @param   x_: value to test for being non zero.
 */
#define UTIL_ASSERT_VAL(x_, ret_)                                           \
    assert_param(x_);                                                       \
    if (!x_)                                                                \
        return ret_;                                                        \

前者用于返回void的函数,而后者则用于返回non-void的函数。我想知道在C11(或更早版本)中是否存在一种机制,该机制仅允许使用带有可变参数数量的单个宏。根据提供给宏的参数数量(1或2),将编译returnreturn ret_

1 个答案:

答案 0 :(得分:2)

有一种方法可以执行标准C这类的事情。首先,您有一个核心宏可以同时处理两种情况

#define ASSERT0(X, RET, ...) 
   /* put your stuff here that only uses X and RET, and ignores the ... */

如您所见,这会收到三个或更多参数。而且,您必须安排RET只是您需要的情况下的空令牌。

现在您可以在上面放一个包装纸

#define ASSERT1(...) ASSERT0(__VA_ARGS__)

这确保可能在各个参数中包含的逗号将被视为ASSERT0的参数分隔符。

然后可以是用户级别的宏

#define MY_ASSERT(...) ASSERT1(__VA_ARGS__, ,)

这可以确保如果仅在下面使用一个参数ASSERT0的情况下使用它,则会看到一个空的第二个参数。如果用两个参数调用它,ASSERT0只会看到它们。

此外,您还应该考虑将内部宏包装在do { ... } while(0)中。否则,您可能会遇到“悬而未决的else”问题,并使用户感到其他句法影响。