ASSERT是多余的吗?

时间:2009-12-23 23:29:26

标签: c++ c pointers assert

ASSERT(pointer);
pointer->x;

在此代码中,ASSERT似乎是多余的。如果指针为NULL,则指针 - > x无论如何都会失败。我的论点是否正确?

7 个答案:

答案 0 :(得分:33)

断言的重要(如果不是主要的)目的是记录应该保留在代码中某一点的不变量。如果不变量被破坏,assert也可以中止该程序的事实只是锦上添花,虽然是非常有用的。我会说在一个典型的程序中,90%的断言是断言,显然不会失败,永远不会失败。换句话说,assert在很大程度上是一种形式化的评论语言。在某种意义上形式化,这些“注释”是用同一种语言编写的,其余的代码是用(C / C ++)编写的,而不是简单的英语。

在你的代码示例中,断言是告诉你指针在这里不应该为null。这就是它存在的原因。从这个意义上说,assert并不是多余的。

就执行流而言,assert总是多余的,这就是为什么断言通常不在代码的发行版本中编译的原因。没有什么可以阻止你在释放代码中保留断言,但通常是通过引入一种特殊的“释放断言”来完成的。在任何情况下,使代码的主要功能取决于断言所采取的操作并不是一个好的编程习惯。就代码的主要功能而言,断言应该是多余的。

答案 1 :(得分:19)

是的,但pointer->x将(我推测)将以不受控制的方式失败,而assert将失败并告诉您确切的位置。

在某种意义上,assert 总是多余,当然。

答案 2 :(得分:2)

不,这不是多余的。在发生任何不良事件之前,断言将停止执行。另一方面,如果你取消引用一个无效的指针,你可能会导致真正的腐败,或者至少是一个不受控制的段错误,而不是一个受控制的堕胎。

答案 3 :(得分:0)

在某些情况下,assert可用于调试 http://simonwillison.net/2008/May/22/debugging/

答案 4 :(得分:0)

ASSERT不是C标准的一部分,因此可以是任何

 #define ASSERT(x) do { \
     x = malloc ( sizeof *x ); \
     memset ( x, 0, sizeof *x );\
     } while ( 0 )

assert是另一回事。

有些人有一个调用调试器的ASSERT宏,有些人调用其他调试或日志,并使用预处理器的字符串化功能。

你真的必须说明这个宏能让任何人知道它是否重要。

答案 5 :(得分:0)

ASSERT也可用于检查可能不会导致崩溃的无效或不合逻辑的情况。这是一个可怕的人为例子:

void cpu_hog(int duration)
{
    int start_time = (int) time(NULL);
    int end_time   = start_time + duration;

    ASSERT(end_time > start_time);  /* If this fails, "int" is too small. */

    while ((int) time(NULL) < end_time)
        ;
}

一个小注释:ASSERT的大多数支持者建议您仅使用它来验证您在编写代码时所做的假设(例如,指针是非NULL,或者条件不会发生)。使用ASSERT来捕获预期会发生的与用户相关的错误或异常(例如,磁盘已满)通常被认为是错误的想法,因为(1)ASSERT存在仅在调试版本中,(2)即使您将调试代码提升为生产版,它也会崩溃而不是优雅地处理条件。

答案 6 :(得分:-1)

ASSERT不会失败。它是在断点上停止调试器。这不会影响发布版本。