do while(0)或者是否哪一个对单个出口点有利?

时间:2017-05-19 08:21:17

标签: c misra

我想实现一个函数的单一退出点。一种方法是使用变量,检查条件,如果条件失败,将变量设置为error并在函数末尾返回该变量。但嵌套if else会妨碍代码的可读性。

其他方法是将代码括在do {} while(0);中并在此循环内检查条件,如果条件失败,则在变量中设置错误并从循环中断,然后返回错误,这样可以提高代码的可读性。

那么哪一个更好嵌套if else或do while(0)?

2 个答案:

答案 0 :(得分:4)

使用goto语句在return语句之前(或之前的某个位置)放置一个标签会如何?

   //...
   // if (...)
      goto exit_func;
   //...
   // if (...)
      goto exit_func;
   //...
   // if (...)
      goto exit_func;
   //...
exit_func:
   // do some common stuff before leaving the function (e.g.: releasing resources)
   // ...
   return;

答案 1 :(得分:1)

虽然您可能不同意MISRA规则,但您不应该找到创造性的尝试,例如将代码包装在do {} while(0);实现单点退出,或者作为编写更少代码的方法。

MISRA禁止转到,所以尽管使用goto跳转到函数中的公共出口点是一种常见的习惯用法,但它不会传递MISRA规则。

即使你觉得它很冗长,你也应该把代码写成例如。

if

并且您不应该找到避免使用嵌套static int32 CFE_ES_GetAppInfoImpl(CFE_ES_AppInfo_t *AppInfo, uint32 AppId) { int32 ReturnCode; if ( CFE_ES_Global.AppTable[AppId].RecordUsed == TRUE ) { CFE_ES_GetAppInfoInternal(AppId, AppInfo); ReturnCode = CFE_SUCCESS; } else { CFE_ES_WriteToSysLog("CFE_ES_GetAppInfo: App ID Not Active: %d\n",(int)AppId); ReturnCode = CFE_ES_ERR_APPID; } return ReturnCode; } int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, uint32 AppId) { int32 ReturnCode = CFE_SUCCESS; if ( AppInfo != 0 ) { if ( AppId < CFE_ES_MAX_APPLICATIONS ) { ReturnCode = CFE_ES_GetAppInfoImpl(AppInfo, AppID); } else { CFE_ES_WriteToSysLog("CFE_ES_GetAppInfo: App ID Exceeds CFE_ES_APPLICATION_MAX: %d\n",(int)AppId); ReturnCode = CFE_ES_ERR_APPID; } } else { CFE_ES_WriteToSysLog("CFE_ES_GetAppInfo: Invalid Parameter ( Null Pointer )\n"); ReturnCode = CFE_ES_ERR_BUFFER; } return(ReturnCode); } /* End of CFE_ES_GetAppInfo() */ 语句来处理单个出口点的变通方法。

如果您的代码涉及许多嵌套语句,您应该将您的函数分解为更小的部分,每个部分都可以处理自己的部分以减少嵌套。

虽然上面的代码很冗长,但它仍然足够小,不需要分手,但作为演示,它可能是

{{1}}