用断言发现bug

 在Symbian OS中,在e32def.h中定义了两个断言宏
#define __ASSERT_ALWAYS(c,p) (void)((c)||(p,0))

#if defined(_DEBUG)
#define __ASSERT_DEBUG(c,p) (void)((c)||(p,0))
#endif

如果断言条件c为假,那么过程p将被调用。断言宏默认情况下并不是产生严重错误,而是允许指定过程以供断言失败时调用。这虽然给了你更多的控制权,但还是应该中止代码执行并标记出错误所在,而不只是返回一个错误码或异常退出。

当断言失败时,总是应该抛出一个严重错误。

__ASSERT_DEBUG

For Example:
void CTestClass::TestValue(TInt aValue)
{
#ifdef _DEBUG
_LIT(KPanicDescripter, "TestValue");
#endif

__ASSERT_DEBUG(aValue >= 0, User::Panic(KPanicDescripter, KErrArgument));

//...
}
但,当在使用多个断言时,上面的示例显然有些麻烦。可以定义一个panic utility function,它带有自己的panic category string,以及一组类的panic enumerators specific。可以在CTestClass类中加入下列枚举,以免污染全局的命名空间。

enum TTestClassPanic
{
EInvalidData, // = 0
EUninitializedValue // = 1
//...
};
然后定义一个严重错误(panic)函数,或者作为类的成员,或者作为一个静态成员函数放在类的实现文件中:
static void Panic(TInt aCategory)
{
_LIT(KTestClassPanic, "CTestClass-Panic");
User::Panic(KTestClassPanic, aCategory);
}
然后示例中的函数可以如下:
void CTestClass::TestValue(TInt aValue)
{
_ASSERT_DEBUG(aValue >= 0, Panic(EUninitializedValue));
//...
}

如果不想或不需要一组enumerated panic values,并且你认为外部的调用者不需要跟踪一个严重错误,可以使用一个轻量级的、匿名的断言。
#define ASSERT(x) __ASSERT_DEBUG(x,User::Invariant())

不要将有副作用的代码放进断言!不管对__ASSERT_DEBUG还是__ASSERT_ALWAYS断言,都应该遵守这个准则。

__ASSERT_ALWAYS

在发布版本中仍需要防御非法使用,但使用__ASSERT_ALWAYS断言的情况并不多。断言会中止代码执行,发生严重错误,显示讨厌的“程序关闭”对话框,这些应该尽量避免。另外,还应该考虑断言对代码速度和空间大小的影响。

如果不使用__ASSERT_ALWAYS断言检测输入值,应该采用其他防御技术,例如用一组if语句来检测输入值,并在错误时返回错误代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值