How is this code structure organized? Goto or do... While (0 )?

Source: Internet
Author: User

Thank you for your enthusiastic reply yesterday. I look up at the night sky, and the stars are shining like the eyes of all of you. This makes me realize that not only can I share the results, but also can I share confusion and loneliness. (This is the end of the opening remarks ~)
In normal programming, I found that this structure is easy to encounter:
(Solution 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;
}
As mentioned above, the indentation level may increase. To avoid this situation, you can change it:
(Solution 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;
}
In this way, new problems are raised. The cleanup task is troublesome each time when return FALSE is returned. If a new HANDLE is introduced in each step, subsequent cleanup will become very heavy. Someone recommends do... The while (0) structure. Someone recommends goto. The two forms are --
Do... While (0 ):
(Solution 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;
}
This structure can avoid a bunch of cleanup operations before return FALSE every time, but the disadvantage is that there are several dependent HANDLE, so we need to nest several layers of do... While (0), sometimes there are three or four layers of nesting.
Goto:
(Scheme No. 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;
} (Solution No. 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;
}

//...

If (! LookupPrivilegeValue (...))
{
Goto ERROR_LEVEL2;
}

If (! AdjustTokenPrivileges (hToken ,...))
{
Goto ERROR_LEVEL2;
}

BRet = TRUE;

ERROR_LEVEL2:
CloseHandle (hToken );
ERROR_LEVEL1:
CloseHandle (hProcess );
ERROR_LEVEL0:
Return bRet;
}
(Which one is better on the left and right ...?)
In this case, the goto solution seems perfect. However, if goto encounters C ++, the disadvantages are shown. In the following section, do... The while (0) structure (only one layer of nesting, which is reasonable here ):
BOOL foo ()
{
HRESULT hr = CoInitializeEx (0, COINIT_MULTITHREADED );

While (true)
{
If (FAILED (hr ))
{
Break;
}

Hr = CoInitializeSecurity (NULL,-1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );

If (FAILED (hr ))
{
Break;
}

CComPtr <IWbemLocator> pLoc = NULL;
Hr = pLoc. CoCreateInstance (CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER );

If (FAILED (hr ))
{
Break;
}

CComPtr <IWbemServices> pSvc = NULL;
Hr = pLoc-> ConnectServer (_ T ("ROOT \ CIMV2"), NULL, 0, NULL, NULL, & pSvc );

If (FAILED (hr ))
{
Break;
}

Hr = CoSetProxyBlanket (pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );

If (FAILED (hr ))
{
Break;
}

CComPtr <IEnumWbemClassObject> pEnum = NULL;
_ Bstr_t bstrLang = _ T ("WQL ");
_ Bstr_t bstrSql = _ T ("SELECT * FROM _ InstanceCreationEvent WITHIN 10 ")
_ T ("WHERE TargetInstance ISA 'win32 _ LogonSession 'AND (TargetInstance. LogonType = 2 OR TargetInstance. LogonType = 11 )");
Hr = pSvc-> execicationicationquery (bstrLang, bstrSql, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, & pEnum );

If (FAILED (hr ))
{
Break;
}

ULONG uCount = 1;
CComPtr <IWbemClassObject> pNext = NULL;
Hr = pEnum-> Next (WBEM_INFINITE, uCount, & pNext, & uCount );

If (FAILED (hr ))
{
Break;
}

//...

Break;
}

CoUninitialize ();

Return SUCCEEDED (hr );
}
If you change to goto, you need to put all the definitions of the required objects at the beginning. Otherwise, goto will skip their initialization and compilation will fail. However, all objects are defined at the beginning, which violates the out-of-the-box declaration rules and is confusing if there are too many objects.
Finally, the question is, How do you organize Code in case of multi-layer nesting of C ++?
Thank you!

 

 

From stream comics

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.