C/C++技巧 异常处理的优雅do while(0)
			 2023-06-06
			  23
			 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语句巧妙地进行流程跳转,优化了代码结构。
			C/C++技巧
			




