สำหรับฉันdo{...}while(0)
เป็นเรื่องปกติ หากคุณไม่ต้องการที่จะเห็นdo{...}while(0)
คุณสามารถกำหนดคำหลักทางเลือกสำหรับพวกเขา
ตัวอย่าง:
//--------SomeUtilities.hpp---------
#define BEGIN_TEST do{
#define END_TEST }while(0);
//--------SomeSourceFile.cpp--------
BEGIN_TEST
if(!condition1) break;
if(!condition2) break;
if(!condition3) break;
if(!condition4) break;
if(!condition5) break;
//processing code here
END_TEST
ฉันคิดว่าคอมไพเลอร์จะลบwhile(0)
เงื่อนไขที่ไม่จำเป็นในdo{...}while(0)
ในรุ่นไบนารีและแปลงตัวแบ่งเป็นการกระโดดแบบไม่มีเงื่อนไข คุณสามารถตรวจสอบเวอร์ชั่นภาษาแอสเซมบลีเพื่อให้แน่ใจ
การใช้goto
ยังสร้างโค้ดที่สะอาดขึ้นและมันตรงไปตรงมากับลอจิกจากนั้นกระโดด คุณสามารถทำสิ่งต่อไปนี้:
{
if(!condition1) goto end_blahblah;
if(!condition2) goto end_blahblah;
if(!condition3) goto end_blahblah;
if(!condition4) goto end_blahblah;
if(!condition5) goto end_blahblah;
//processing code here
}end_blah_blah:; //use appropriate label here to describe...
// ...the whole code inside the block.
หมายเหตุ: }
ฉลากถูกวางไว้หลังจากปิด นี่คือการหลีกเลี่ยงปัญหาที่เป็นไปได้หนึ่งข้อในgoto
การวางรหัสโดยบังเอิญเพราะคุณไม่เห็นป้ายกำกับ ตอนนี้มันเป็นเหมือนdo{...}while(0)
ไม่มีรหัสเงื่อนไข
ในการทำให้โค้ดนี้สะอาดและเข้าใจง่ายขึ้นคุณสามารถทำได้:
//--------SomeUtilities.hpp---------
#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_
//--------SomeSourceFile.cpp--------
BEGIN_TEST
if(!condition1) FAILED(NormalizeData);
if(!condition2) FAILED(NormalizeData);
if(!condition3) FAILED(NormalizeData);
if(!condition4) FAILED(NormalizeData);
if(!condition5) FAILED(NormalizeData);
END_TEST(NormalizeData)
ด้วยสิ่งนี้คุณสามารถทำบล็อกซ้อนกันและระบุตำแหน่งที่คุณต้องการออก / กระโดดออก
//--------SomeUtilities.hpp---------
#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_
//--------SomeSourceFile.cpp--------
BEGIN_TEST
if(!condition1) FAILED(NormalizeData);
if(!condition2) FAILED(NormalizeData);
BEGIN_TEST
if(!conditionAA) FAILED(DecryptBlah);
if(!conditionBB) FAILED(NormalizeData); //Jump out to the outmost block
if(!conditionCC) FAILED(DecryptBlah);
// --We can now decrypt and do other stuffs.
END_TEST(DecryptBlah)
if(!condition3) FAILED(NormalizeData);
if(!condition4) FAILED(NormalizeData);
// --other code here
BEGIN_TEST
if(!conditionA) FAILED(TrimSpaces);
if(!conditionB) FAILED(TrimSpaces);
if(!conditionC) FAILED(NormalizeData); //Jump out to the outmost block
if(!conditionD) FAILED(TrimSpaces);
// --We can now trim completely or do other stuffs.
END_TEST(TrimSpaces)
// --Other code here...
if(!condition5) FAILED(NormalizeData);
//Ok, we got here. We can now process what we need to process.
END_TEST(NormalizeData)
รหัสสปาเก็ตตี้ไม่ใช่ความผิดของgoto
มันเป็นความผิดของโปรแกรมเมอร์ คุณยังสามารถสร้างรหัสสปาเก็ตตี้ได้โดยไม่ต้องใช้goto
คุณยังคงสามารถผลิตรหัสปาเก็ตตี้โดยไม่ต้องใช้