如何使用断言功能

时间:2012-10-14 21:48:32

标签: c++ c

什么是

assert( scanf("%d", &t) == 1 ); 

assert( 1 <= t && t <= 10 ); 

返回?

我的目标是从1到10包含t

6 个答案:

答案 0 :(得分:7)

不要将assert与用户输入一起使用。断言旨在捕获逻辑错误(通过在断言失败时调用abort),使程序崩溃,用户输入永远不会导致程序崩溃。

但是要回答你的问题,如果定义了NDEBUG,那么断言什么都不做。这可能是您的程序没有按预期崩溃的原因。

答案 1 :(得分:6)

您可以假设断言声明如下:

/*!
 * Immediately crash the program if assumption is proven invalid.
 */
void assert (bool assumption);

如果您“知道”变量t永远不会超出范围[1,10],因为您编写了代码,而您的代码无法生成任何其他值 ,那么断言该陈述是合适的。

断言明显的事情

考虑以下对断言的使用:

int t = 9;
assert (9 == t);   // A very valid assertion, if a little pedantic.

上面的代码应该看起来很明显。断言的表达式 (显然)是真的,但更重要的是任何其他结果都是疯狂的。学习t != 9将消除你对C ++如何工作的所有假设,计算机如何执行数学和存储值,是否存在或意识是否仅仅是由如此多的加重电子形成的错觉......

但那是断言的价值。

即便如此,计算机实际上是100%确定性的,“疯狂”的事情。这也不罕见。实际上,我们将断言写入我们的代码显式以检测这些情况,并让我们有机会弄清楚发生了什么。 在此考虑一些疯狂行为的现实原因

“疯狂”行为的原因

你的断言应该防止出现......

等错误
  1. 线程同步不正确。

    int t;
    
    // Thread 1
    t = 9;
    assert(t == 9);
    
    // Thread 2
    t = 3;
    assert(t == 3);
    
  2. 内存管理不善。

    class X {
        void sayHello () {
            assert(this != NULL);   // An object that does not exist cannot say hello.
            std::cout << "Hello?" << std::endl;
        }
    };
    
    // Without the assertion, this code would actually run!
    X* x = NULL;
    x->sayHello();
    
  3. 堆栈(或堆)损坏。

    (有关合理的例子,请参阅Stack corruption in C++。)

  4. 行为不方便,但不是疯了:

    虽然它可能会彻底改变程序的执行路径,但这些内容对于断言而言不合适。抛出异常,打印错误,很好地关闭程序,并负责任地清理程序的资源。 不要断言这些“失败”!

    1. 用户输入的内容很荒谬。

      int t;
      scanf("%d", &t);
      assert ( 0 <= t <= 10 );       // What, are you friends with this user?
                                     // You're going to let him crash your program?
      
    2. 某些I / O设备出现故障。

      int s = socket();
      // blah blah connect blah blah
      
      char buffer[64];
      int bytes_received = recv(s, buffer, 64, NULL);
      assert (bytes_received > 0);   // Do you know how hard it is to send a packet
                                     // from Estonia to the US?!
      
    3. 此列表不完整,但它应该为您提供更广泛的指导,说明如何(以及如何)应用断言。

答案 2 :(得分:1)

Assert不返回任何内容,如果参数为false,则程序终止。断言是针对不应该发生的情况......但是你要检查以防万一你误以为。

http://www.cplusplus.com/reference/clibrary/cassert/assert/

答案 3 :(得分:1)

assert( expression );​

assert做的是评估表达式,如果它的评估结果与0 / false比较,则程序终止。

答案 4 :(得分:1)

这是我期望的那种答案:

具体说明

#include <assert.h> 

在源文件开头的单独行中。

现在,只要bool不成立,你就可以使用assert(bool)终止你的程序。

(其他答案是关于这个问题:“如何正确使用断言”)

答案 5 :(得分:0)

解决问题的正确方法是将scanf()函数封装在一个知道它正在做什么的函数中:

int AskNumberOfWidgetFrobs() {
  int count = 0;
  for(;;) // Until we get a valid number
    scanf("%d", &count);
     if (count > 0 && count <= 10) {
       return count;
    } else {
       printf("%d is not a valid number of WidgetFrobs\n", count);
    }
  }
}