2

我想写断言语句但不中止程序。所以也许使用与 assert() 完全相同的语法,但称为 expect()。当然我可以自己写,但是 assert 非常聪明(例如,它不仅知道文件和行号,还知道不正确的表达式)。我当然可以深入研究图书馆和 Cv/Cc 解决方案。但这是一个如此明显的通用要求,我不敢相信已经没有一个好的解决方案。当然应该在这里很容易找到...

4

3 回答 3

9

这是因为assertis 是一个预处理器宏,因此可以使用__LINE__and__FILE__宏,因为整个宏调用被扩展为一行。

您可以轻松制作自己的:

#define expect(value, message) \
    do \
    { \
        if (!(value)) \
        { \
            fprintf(stderr, "%s failed in %s:%d\n", #value, __FILE__, __LINE__); \
        } \
    } while(0)
于 2013-05-26T10:48:57.033 回答
2

不,没有这样的事情。但是,它很容易写成:

#define expect( chk )  \ 
    if (!(chk)) \
        printf("Assertion (%s) failed %s at line %d ", #chk, __FILE__,__LINE__);

这个测试:

int main()
{
  expect(0);
  expect(1);

  return 0;
}

将打印第一个失败的断言:

Assertion (0) failed t.c at line 8 

现场演示。

于 2013-05-26T10:49:35.343 回答
2

归功于 BЈовић

#ifdef  NDEBUG
#define expect(chk) ((void *)0)
#else
#define expect(chk) (chk ? (void) (0) : fprintf(stderr,"%s:%d %s: expectation (%s) failed.\n", __FILE__ , __LINE__ , __func__ , #chk))
#endif

这个版本

  • 写入标准错误,而不是标准输出
  • 可以像 assert() 一样使用 NDEBUG 宏禁用

它看起来尽可能像 assert() 消息,尽管它当然没有 assert 在其他参数方面的灵活性。

我不明白为什么强制使用分号是有用的——因为如果有分号它可以工作,如果没有它仍然有效!

不过,像 try...catch around assert() 这样更聪明的解决方案是我希望得到的答案!

于 2013-05-26T13:05:45.963 回答