zhangJW_cn 阅读(1206) 评论(2)
由于STB上调试不方便,故而release的逻辑错误,采取提示到终端的方法。方法:通过使用kAssert替换crt原生的assert,
#ifdef KYLIN_DEBUG_MODE
# define kAssert( X ) assert( X )
#else
static inline void __kassert_r__( const char *f,unsigned int l,const char *m,const char *x )
{
std::cerr << "!!!!! Error : " << f << "," << l << "," << m << " " << x << " !!!!!" << std::endl;
}
# define kAssert( X ) if( !(X) ) __kassert_r__( __FILE__,__LINE__,__FUNCTION__,#X )
#endif //KYLIN_DEBUG_MODE

上面的宏,表面看基本正确,在实际使用中也没有发生问题。不过,下面的使用情况触发了其缺陷(debug版测试正常,release表现异常)。
inline void WriteBytes( const void *data,kUInt32 size )
{
const kUInt32 pos = mWrite + size;
if( pos <= mSize ) memcpy( mData+mWrite,data,size );
else if( !mInner ) kAssert( false );
else memcpy( _AllocBuffer(pos)+mWrite,data,size );
mWrite += size;
}
由于之前的使用中均正常,脑子里默认并将kAssert世卫正确,这时候在一个复杂的系统里想尽了办法却悲剧依然。

正确的解法应该是采用如下定义:
#ifdef KYLIN_DEBUG_MODE
# define kAssert( X ) assert( X )
#else
static inline void __kassert_r__( bool b,const char *f,unsigned int l,const char *m,const char *x )
{
if( !b ) std::cerr << "!!!!! Error : " << f << "," << l << "," << m << " " << x << " !!!!!" << std::endl;
}
# define kAssert( X ) __kassert_r__( X,__FILE__,__LINE__,__FUNCTION__,#X )
#endif //KYLIN_DEBUG_MODE

现在或许能够总结和讲出道理,不过在事中就悲剧了,成本是相当高昂的,故而记录于此(也可视为分享)。

评论列表
zw
re: 真实的陷阱1 — 错误的宏定义
。。。使用宏定义复合语句,可以使用do{} while(0)这种方式
zw
re: 真实的陷阱1 — 错误的宏定义
开了全部警告后,gcc来了句:
warning: suggest explicit braces to avoid ambiguous ‘else’

发表评论
切换编辑模式