读misc。 与SDL开发相关的教程我发现了两个不同的例子,做同样的事情,但是以不同的方式。 从代码“安全性”和可维护性的角度来看,我想知道你认为哪两个是正确的。
在第一个例子中,程序员根本没有使用断言,但代码看起来还不错(至少在我看来):
int main(){ SDL_Surface *screen; /** Initialize SDL */ if(SDL_Init(SDL_INIT_VIDEO)!=0){ fprintf(stderr,"Unable to initialize SDL: %s",SDL_GetError()); } atexit(SDL_Quit); /** Sets video mode */ screen=SDL_SetVideoMode(640,480,16,SDL_HWSURFACE); if(screen==NULL){ fprintf(stderr,"Unable to set video mode: %s",SDL_GetError()); } return (0); }
在第二个例子中,程序员[其他]正在使用不同的方法,例如(代码不完全是复制粘贴):
int main(){ SDL_Surface* screen; /** Initialize SDL */ assert(SDL_Init(SDL_INIT_VIDEO)==0); atexit(SDL_Quit); /** Sets video mode */ screen=SDL_SetVideoMode(640,480,16,SDL_HWSURFACE); assert(screen!=NULL); return (0); }
是否可以在if条件(从第一个示例)中“替换”与第二个示例中的断言一样?
什么是正确的策略(如果有的话)?
做替换是不行的。 第二个例子是错误的 ,因为assert(x)
在非调试版本中扩展为空(当定义了NDEBUG
时)。 这意味着上面assert
中的指针检查将从发布版本中的代码中删除。 这绝对是错误的。
那么,何时应该使用assert
? 它对于记录和调试很有用。 在某种程度上,你说,“我确信这种情况是正确的,我把它作为一个assert
来在调试过程中捕获错误的代码,并将条件记录给代码的读者”。
因此,两个例子之间存在巨大差异。 对于像检查malloc
的返回值这样的事情, assert
是错误的,因为不能保证它们将返回非NULL
,并且如上所述, assert(x)
表示“我完全确定x
是真的”,而不是只是“如果x
不是真的,那就太糟糕了”。 为此,使用if(x) good(); else bad();
if(x) good(); else bad();
控制。
SDL_Init
和SDL_SetVideoMode
可以分别返回-1
和NULL
。
当事情出错时,应以意想不到的方式使用assert
。 通常,如果断言失败,则表示程序中存在错误。 断言不会用于可能发生的预期错误(即无法打开文件,无法初始化某些内容,等等)。
在您提供的示例中, assert
似乎不是最合理的解决方案。 当程序无法初始化SDL时,更有意义的是以结构化方式告诉用户而不是抛出断言(这可能只会在某些系统上导致seg-fault)。
断言语句通常仅用于调试版本,并将暂停程序,并且通常允许您进入调试器。 在发布版本中,仍然可以检查错误情况。 一种简单的方法可能是这样的:
assert( condition ); if ( !condition ) handle error;
我使用断言来记录前置条件和后置条件。 (确定function的意图)
喜欢..
double positive_division(double dividend, double divisor) { //preconditions ASSERT(dividend>=0); ASSERT(divisor >0); double quotient = dividend/divisor; //postconditions ASSERT(quotient>=0); return quotient; }
以上就是c/c++开发分享如何使用C断言使代码更安全?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562459.html