【发布时间】:2019-03-09 07:39:10
【问题描述】:
我有 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 的函数,而后者用于返回非 void 的函数。我想知道在 C11(或更早版本)中是否有一种机制允许人们仅使用具有可变参数数量的单个宏。根据提供给宏的参数数量(1 或 2),将编译 return 或 return ret_。
【问题讨论】:
-
闻起来像“XY 问题”。您可能应该做的只是
assert(param1); assert(param2); ...。触发断言时从函数返回有什么意义? -
@Lundin 在一般情况下没有意义。但首先 - 你应该总是处理所有情况,所以无论如何你总是在断言之后返回。其次,仅当程序在由操作系统控制的环境中运行时才有意义,这将在断言时停止它。在没有操作系统和许多线程的嵌入式系统中,当发生分段错误时,可能会发生不好的事情。还取决于断言实现,它并不总是停止线程。
-
在实际系统中,您总是会在出错时返回错误代码;如果 void 函数出现错误,您不会只是默默地崩溃。所以你的场景是不现实的。您不会有一个函数返回
void,另一个函数返回int,而是一个函数类型返回err_t或其他。此外,裸机系统首先应避免使用 assert()。 -
@Lundin assert 是一个调试工具。它甚至没有在发布版本中编译。它的存在仅对开发目的有意义,并且在发布版本中不予考虑。如果感觉应该这样,那么功能就没有以正确的方式构建。您正在描述不同的机制。
-
这就是我的意思,在发布构建的情况下,断言将不存在,因此您的 void 函数只会静默返回,并且程序无法判断发生了错误。这简直是糟糕的设计。此外,嵌入式系统通常会将参数验证留给调用者,因为它可能很昂贵。
标签: c macros c11 variadic-macros