हाँ, प्रवाह को नियंत्रित करने के लिए मैक्रो दो संयुक्त निर्माणों नफरत करते थे। क्या यह उतना बुरा है जितना लगता है या इसे गोटो के उपयोग को नियंत्रित करने और उचित सफाई रणनीति प्रदान करने के लिए एक अच्छा तरीका माना जा सकता है?साथ 'गोटो'
काम पर हमने हमारे कोडिंग मानक में गोटो को अनुमति देने या नहीं करने के बारे में चर्चा की थी। आम तौर पर कोई भी गोटो के मुफ्त उपयोग की अनुमति नहीं देना चाहता था, लेकिन कुछ क्लीनअप कूद के लिए इसका इस्तेमाल करने के बारे में सकारात्मक थे। इस कोड में के रूप में:
void func()
{
char* p1 = malloc(16);
if(!p1){
return;
}
char* p2 = malloc(16);
if(!p2){
free(p1);
return;
}
char* p3 = malloc(16);
if(!p3){
free(p1);
free(p2);
return;
}
}
विशेष रूप से निर्माता की तरह काम करता है में
कई आवंटन इस कर सकते हैं साथ:
void func()
{
char* p1 = malloc(16);
if(!p1)
goto cleanup;
char* p2 = malloc(16);
if(!p2)
goto cleanup;
goto norm_cleanup;
err_cleanup:
if(p1)
free(p1);
if(p2)
free(p2);
norm_cleanup:
}
इस तरह के प्रयोग की abovious लाभ आप इस कोड के साथ खत्म करने की जरूरत नहीं है कि है कभी-कभी बहुत बुरा हो जाता है, कम से कम नहीं जब किसी को बीच में कुछ डालना पड़ता है।
तो, क्रम में गोटो उपयोग करने के लिए सक्षम होने के लिए, लेकिन अभी भी स्पष्ट रूप से यह स्वतंत्र रूप से इस्तेमाल किया जा रहा से अलग, प्रवाह को नियंत्रित करने मैक्रो का समूह काम से निपटने के लिए बनाया गया था।
int func()
{
char* p1 = NULL;
char* p2 = NULL;
char* p3 = NULL;
FAIL_SECTION_BEGIN
{
p1 = malloc(16);
FAIL_SECTION_DO_EXIT_IF(!p1, -1);
p2 = malloc(16);
FAIL_SECTION_DO_EXIT_IF(!p2, -1);
p3 = malloc(16);
FAIL_SECTION_DO_EXIT_IF(!p3, -1);
}
FAIL_SECTION_ERROR_EXIT(code)
{
if(p3)
free(p3);
if(p2)
free(p2);
if(p1)
free(p1);
return code;
}
FAIL_SECTION_END
return 0;
यह अच्छा लग रहा है, और बहुत से लाभ के साथ आता है, लेकिन, वहाँ किसी भी कमियां हम के बारे में सोच किया जाना चाहिए रहे हैं:
#define FAIL_SECTION_BEGIN int exit_code[GUID] = 0;
#define FAIL_SECTION_DO_EXIT_IF(cond, exitcode) if(cond){exit_code[GUID] = exitcode; goto exit_label[GUID];}
#define FAIL_SECTION_ERROR_EXIT(code) exit_label[GUID]: if(exit_code[GUID]) int code = exit_code[GUID];else goto end_label[GUID]
#define FAIL_SECTION_END end_label[GUID]:
हम इस प्रकार के रूप में उपयोग कर सकते हैं: कुछ इस तरह (सरलीकृत) लग रहा है इसे विकास में लाने से पहले? यह सभी प्रवाह नियंत्रण के बाद है और goto: ish। दोनों निराश हैं। इस मामले में उन्हें निराश करने के लिए तर्क क्या हैं?
धन्यवाद।
मार्टिन फिडो अपने जवाब में बताते हैं, अंतिम कोड स्निपेट में पॉइंटर्स पी 1, पी 2 और पी 3 त्रुटि-हैंडलिंग सेक्शन में से बाहर हैं, और पहले कोड स्निपेट पी 2 में कचरा डेटा होगा (यदि यह संकलित करता है बिल्कुल - सी नियमों के बारे में निश्चित नहीं है)। –
@j: मुझे यकीन है कि यह कोड संकलक के माध्यम से भी नहीं जाएगा। टिप के लिए धन्यवाद, लेकिन आप सवाल के पूरे बिंदु को याद किया होगा। – sharkin
@ आरएए: आपको क्या लगता है कि मैंने इस बिंदु को याद किया? गैर-compilability एक भ्रमित पक्ष मुद्दा था कि मैंने सोचा था कि एक टिप्पणी में इंगित करने लायक था। –