C/C++技巧 异常处理的优雅do while(0)
2023-06-06
9
0
编写函数代码时,如果有大量的判断,如果失败就应该返回,但返回前需要释放上面申请的资源,比如说说堆内存的释放,句柄的关闭等。
那么如果这种情况很多,代码就会繁琐不堪,前且也很容易遗忘一些资源的释放,当后续再次修改代码时,代码又很不清晰。
假如有如下代码,对文件进行复制功能:
bool Test()
{
FILE* fw = fopen("write.txt", "wb");
if (fw == NULL)
{
return false;
}
FILE* fr = fopen("read.txt", "wb");
if (fr == NULL)
{
fclose(fw);
return false;
}
fseek(fr, 0, SEEK_END);
int len = ftell(fr);
fseek(fr, 0, SEEK_SET);
char* pdata = (char*)malloc(len);
if (pdata == NULL)
{
fclose(fw);
fclose(fr);
return false;
}
fread(pdata, 1, len, fr);
fwrite(pdata, 1, len, fw);
fclose(fw);
fclose(fr);
return true;
}
我们发现在每一步失败时都要释放上面已经申请到的资源,资源少了还好,资源太多,写的代码就有点难看了。
这里我们可使用do while(0)来进行代码结构优化:
bool Test()
{
bool isok = false;
FILE* fr = NULL;
FILE* fw = NULL;
char* pdata = NULL;
do
{
fw = fopen("write.txt", "wb");
if (fw == NULL)
{
break;
}
fr = fopen("read.txt", "wb");
if (fr == NULL)
{
break;
}
fseek(fr, 0, SEEK_END);
int len = ftell(fr);
fseek(fr, 0, SEEK_SET);
char* pdata = (char*)malloc(len);
if (pdata == NULL)
{
break;
}
fread(pdata, 1, len, fr);
fwrite(pdata, 1, len, fw);
isok = true;
} while (0);
if (fw != NULL)
{
fclose(fw);
}
if (fr != NULL)
{
fclose(fr);
}
if (pdata != NULL)
{
free(pdata);
}
return isok;
}
这里我们可以看到,使用do while(0)只执行一次,用while循环的break语句巧妙地进行流程跳转,优化了代码结构。