0

我有一个assert可以解析为 的宏,if如下所示:

#define assert(expr) \
if (!(expr)) \
{ \
    handle_failed_assert(); \
}

忽略如何handle_failed_assert()工作,你不需要引用这个do { ... } while(0)技巧。请关注这背后的功能。

现在,真正的问题来了。有时我想强迫和断言,让它有意义。所以我们使用这个:

assert(!"Assert cause carefully described.");

问题是我们有这个基于RVCT 2.2的编译器vrxcc ,它在编译时会抛出这个警告:

#236-D: controlling expression is constant

当然,这会解析为 compile constant if

我怎么能欺骗编译器接受它?

4

1 回答 1

2

你的问题最终归结为“我的编译器太聪明了,我如何让它停止抱怨一些事情,是的,是真的,通常是程序员的错误,但在这种情况下不是程序员的错误”。只有两种方法可以做到这一点:

  • 智胜编译器。这取决于编译器。
  • 告诉编译器“不要抱怨,这不是错误”。这取决于编译器。

我对vrxcc一无所知。R 的评论倾向于做第一个。这种事情几乎可以保证工作:

extern int __truefunc(void);
#define assert(expr) ((__truefunc() && (expr)) || __assert_fail(#expr))

wheretruefunc是一个始终返回 1 的函数,您可以单独编译以智取编译器。当然,代价是该死的无用运行时调用。

“告诉编译器”方法更好,但需要某种编译器文档帮助。


附录:我在淋浴时突然想到,在你的特殊情况下,你已经决定恐慌,所以你可以有一个panic函数,并在这里调用它。缺点是您必须更改所有现有common_assert(!"some string")呼叫,但至少您可以机械地这样做。

如果该语言具有assert内置的两个参数或作为标准的东西,那可能会很好。如今,FreeBSD 内核KASSERT或多或少地用于此用途:

#define KASSERT(expr, panic_args) \
    do { if (!(expr)) panic panic_args; } while (0)

这在语法上有点笨拙,但非常灵活:

KASSERT(foo.field == FOO_MAGIC,
    ("memory overwrite of foo data structure: %d != %d",
        foo.field, FOO_MAGIC));
于 2013-07-04T22:06:34.553 回答