我想实现一个函数的单一退出点。一种方法是使用变量,检查条件,如果条件失败,将变量设置为error并在函数末尾返回该变量。但嵌套if else会妨碍代码的可读性。
其他方法是将代码括在do {} while(0);
中并在此循环内检查条件,如果条件失败,则在变量中设置错误并从循环中断,然后返回错误,这样可以提高代码的可读性。
那么哪一个更好嵌套if else或do while(0)?
答案 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}}