6

在进行编程时,我使用断言以及 NULL 指针验证。

但据我所知,断言仅在调试模式下有用。

我的问题是假设我有一个内部指针,我确信它不能是返回指针的 N​​ULL 示例函数(但指针不是类的成员),在这种情况下我可以使用断言

test* ptr = fun(); // return a pointer of type test
assert(ptr);

//do some operation

NULL指针验证

test* ptr = fun(); // return a pointer of type test
assert(ptr);
if (NULL != ptr)
{
    //do some operation
}

这里哪个代码实践是好的。根据我的理解,它将是第二个。因为我遇到过一些情况,由于一些我们甚至想不到的异常情况,ptr的值返回NULL 。

但是我们还有其他更好的选择吗?

4

5 回答 5

4

assert说“如果这不是真的,我的代码中有逻辑错误”。如果您正在编写代码来处理指针可能为空的事实,那么断言调用是多余的。您应该将日志记录和处理添加到“其他”案例中。这样,您的调试版本将以与发布版本相同的方式运行,即使在空指针情况下也是如此。

如果您的意思是断言并且您必须在空指针上中止,那么在您的发布版本中启用断言或使用另一种启用发布的断言机制。

仅调试断言的唯一原因是检查在发布代码中成本太高的逻辑错误。通常,对指针的空检查不属于此类别。

于 2013-01-11T07:08:02.687 回答
3

真正的解决方案取决于函数的语义fun

如果返回NULL在语义上无效,那么我认为fun应该抛出一个适当的异常(例如std::logic_error1)而不是返回NULL,并且您可以assert在调用站点上使用以确保它fun工作正常,如果它不能正常工作,则中止程序. 通过这种方式,错误fun不会传播到程序的其余部分,因为它会立即被捕获。

但是,如果NULLfun 语义上返回是有效的,那么您应该检查调用站点上的返回值,if并且assert在这种情况下并不真正需要,因为if无论如何您都会使用。

1. 或者你可以使用std::runtime_erroror std::domain_error

于 2013-01-11T06:58:37.430 回答
1

我建议您使用自己的代码进行断言。如您所说,断言仅在调试模式下有效。

所以,如果它在发布模式下工作,它就不起作用。

如果您使用自己的断言代码。您可以简单地找出问题所在。

test* ptr = fun(); // return a pointer of type test
MyOwnAssert(ptr); 

void MyOwnAssert(void* pPointer)
{
   if (NULL == pPointer)
     abort();
}    
于 2013-01-11T07:06:12.873 回答
0

正如您所提到的,断言仅在调试期间,帮助程序员确定他们出错的地方。它在生产中没有任何价值,因此,如果您对指针可能为 NULL 有任何疑问,我更喜欢使用第二种方法。

于 2013-01-11T06:57:10.677 回答
0

你对 assert 所做的选择是你自己的选择:如果你愿意,你可以在生产中使用。

我想说,如果您想及早发现错误,使用 assert() 会更好。特别是如果它是一个 NULL 指针的事实不应该发生。
您甚至可以在其中插入一个Google Breakpad,这样每当您点击 NULL 指针时,您就会发送一份包含完整堆栈的报告。

在可能存在 NULL 指针的情况下(有时是预期的......),那么我猜 NULL 检查会更好。但我想说的是,此时你的代码在某种程度上是错误的,如果它必须适应被传递的 NULL 指针。

于 2013-01-11T07:11:41.873 回答