c - 如何避免 if 上出现 "constant expression"?

标签 c if-statement assert assertions constant-expression

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

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

忽略handle_failed_assert()的工作原理,并且您不需要引用do { ... } while(0)技巧。请重点关注其背后的功能。

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

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

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

#236-D: controlling expression is constant

当然,它解析为编译常量if

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

最佳答案

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

  • 智取编译器。这取决于编译器。
  • 告诉编译器“不要提示,这不是一个错误。”这取决于编译器。

我对vrxcc一无所知。 R 的评论倾向于做第一个。这种事情几乎肯定会起作用:

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

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

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

<小时/>

附录:我在淋浴时突然想到,在您的特定情况下,您已经决定 panic ,因此您可以只拥有一个 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));

关于c - 如何避免 if 上出现 "constant expression"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17478361/

相关文章:

Java:如果语句中有两个或多个条件,if 语句将不起作用吗?

javascript - 如何在 Cypress 中使用逻辑 OR 应该断言

java - 使用 Selenium 和 Eclipse (Java) 断言表格边框的 css 样式

c - 三元运算符使用错误, "ERROR:void value not ignored as it ought to be"

c - 为什么我的结构变量不包含这个成员?

java - 如何将 if-else 语句变成 switch 语句?

python - Unittest 的 assertEqual 和 iterables - 只检查内容

python - SWIG 或 Boost - 用于将 C 结构映射到 Python

c++ - Eclipse CDT 使用主项目编译器设置编译静态库

javascript - 检查命令是否执行