当前位置:编程学习 > C/C++ >>

这种代码结构如何组织?goto or do…while(0)?

灰常感谢各位达人昨天的热心回帖,让我受益匪浅。我仰望夜空,群星点点,就如各位的点睛之语,在无尽的苍穹闪耀。这让我深深地意识到,在这里,不仅可以分享成果,也可以分享困惑、分享寂寞。(开场白到此结束~)
在平常的编程中,我发现很容易遇到这种结构:
(1号方案)
BOOL foo()
{
    BOOL bRet = FALSE;

    HANDLE hProcess = OpenProcess(...);

    if (hProcess != NULL)
    {
        HANDLE hToken = OpenProcessToken(hProcess, ...);

        if (hToken != NULL)
        {
            // ...

            if (LookupPrivilegeValue(...))
            {
                if (AdjustTokenPrivileges(hToken, ...))
                {
                    bRet = TRUE;
                }
            }

            CloseHandle(hToken);
        }

        CloseHandle(hProcess);
    }

    return bRet;
}
如上写法,容易造成缩进级别不断增加。为了避免这种情况,可以改成:
(2号方案)
BOOL foo()
{
    HANDLE hProcess = OpenProcess(...);

    if (hProcess == NULL)
    {
        return FALSE;
    }

    HANDLE hToken = OpenProcessToken(hProcess, ...);

    if (hToken == NULL)
    {
        CloseHandle(hProcess);

        return FALSE;
    }

    // ...

    if (!LookupPrivilegeValue(...))
    {
        CloseHandle(hToken);
        CloseHandle(hProcess);

        return FALSE;
    }

    if (!AdjustTokenPrivileges(hToken, ...))
    {
        CloseHandle(hToken);
        CloseHandle(hProcess);

        return FALSE;
    }

    CloseHandle(hToken);
    CloseHandle(hProcess);

    return TRUE;
}
这样,又引来了新的问题,每次 return FALSE 时的清理任务比较麻烦,要是每步操作都引进新的 HANDLE 的话,后续的清理工作就变得非常繁重。有人推荐do…while(0)的结构,有人推荐goto。这两种形式分别是——
do…while(0):
(3号方案)
BOOL foo()
{
    HANDLE hProcess = OpenProcess(...);

    if (hProcess == NULL)
    {
        return FALSE;
    }

    BOOL bRet = FALSE;

    do
    {
        HANDLE hToken = OpenProcessToken(hProcess, ...);

        if (hToken == NULL)
        {
            break;
        }

        // ...

        BOOL bRetInner = FALSE;

        do
        {
            if (!LookupPrivilegeValue(...))
            {
                break;
            }

            if (!AdjustTokenPrivileges(hToken, ...))
            {
                break;
            }

            bRetInner = TRUE;

        } while (0);

        CloseHandle(hToken);

        if (!bRetInner)
        {
            break;
        }

        bRet = TRUE;

    } while (0);

    CloseHandle(hProcess);

    return bRet;
}
这种结构可以避免每次 return FALSE 前的一堆清理工作,但缺点是,有几个依赖性的 HANDLE,就要嵌套几层的 do…while(0),有时候也会遇到需要三四层嵌套的情形。
goto:
(4.1号方案)

BOOL foo()
{
    BOOL bRet = FALSE;

    HANDLE hProcess = OpenProcess(...);

    if (hProcess == NULL)
    {
        goto CLEAR;
    }

    HANDLE hToken = OpenProcessToken(hProcess, ...);

    if (hToken == NULL)
    {
        goto CLEAR;
    }

    // ...

    if (!LookupPrivilegeValue(...))
    {
        goto CLEAR;
    }

    if (!AdjustTokenPrivileges(hToken, ...))
    {
        goto CLEAR;
    }

    bRet = TRUE;

CLEAR:
    if (hToken != NULL)
    {
        CloseHandle(hToken);
    }

    if (hProcess != NULL)
    {
        CloseHandle(hProcess);
    }

    return bRet;
}  (4.2号方案)

BOOL foo()
{
    BOOL bRet = FALSE;

    HANDLE hProcess = OpenProcess(...);

    if (hProcess == NULL)
    {
        goto ERROR_LEVEL0;
    }

    HANDLE hToken = OpenProcessToken(hProcess, ...);

    if (hToken == NULL)
    {
        goto ERROR_LEVEL1;
    }

   

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,