2011-12-11 79 views
0

例如:断言在本地C++调试期间使用的断言/调试

char* append(char* pStr, const char* pAddStr) 
{ 
    // Verify non-null pointers 

    assert(pStr != nullptr); 
    assert(pAddStr != nullptr); 

    // Code to append pAddStr to pStr... 
} 

调用append()函数在一个简单的程序一个空指针参数产生我的机器上执行以下诊断消息:

Assertion failed: pStr != nullptr, file c:\beginning visual c++ 2010\examples visual studio project files\tryassertion\tryassertion\tryassertion.cpp, line 10 

我想知道是否断言是必要的。如果我可以使用if-else表达式输出自己的错误消息,那么使用它们有什么意义?

回答

4

断言有条件检查;这只是一个宏观那像这样(简化):

#define assert(b) if (!(b)) { std::cerr << ...; exit(1); } 

我能想到的两个优点:

  1. 当您在释放模式编译(即不是在调试模式下),那么所有的assert s将编译为无,因此您不会产生运行时开销。
  2. assert是一个成语;其他程序员知道要查找它们,它们也不同于“正常”控制流。
+0

没问题,thanx! –

1

断言用于确保满足某些基本假设。基本上,在每一种“不可能发生”的情况下,都会提出一个断言,最常用的断言是API如何被使用。先决条件和后置条件(就像你的例子,它包含断言,检查你的追加函数的正确用法)。对于已知在运行时期间发生并且事先无法预防的其他错误(例如文件未找到或权限不足的错误类型),您将必须编写错误处理代码。

断言不包含在发布编译中,因此它们只能用于捕获关键编程错误,这些错误在调试模式测试运行中已经发生。

1

当它们违反的唯一情况是程序逻辑中的错误时,应该使用断言。您使用普通的if - then - else条件来确定可能因输入或外部可能条件(即文件丢失)而发生的事情。

当您确定程序逻辑有问题时,在尝试继续执行时没有太大意义...您的程序与您的想法有所不同(因为否则断言不会被触发)因此最好的选择就是大声疾呼问题并立即死亡。

当代码以“释放”模式编译时,通常会断开断言,即使如果程序逻辑非常复杂,并且如果继续执行生成错误的输出将会产生更大的问题,比停止执行。

请注意,有时新手程序员所谓的“陷阱”是断言,当断言代码被删除以释放模式时,assert中的表达式不再被评估,因此如果您编程取决于副作用那表情就会让你陷入麻烦......例如:

... 
assert(insert_record(db, data) == DB_OK); // <== this is bad 
... 

时断言定义离开插入将根本不会发生,让你有一个程序,不会在发布模式下工作,当您尝试调试的问题,可代替。