Bagi saya do{...}while(0)
itu baik-baik saja. Jika Anda tidak ingin melihatnya do{...}while(0)
, Anda dapat menentukan kata kunci alternatif untuk mereka.
Contoh:
//--------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
Saya pikir kompiler akan menghapus while(0)
kondisi yang tidak perlu di Windowsdo{...}while(0)
dalam versi biner dan mengubah istirahat menjadi lompatan tanpa syarat. Anda dapat memastikan versi bahasa assemblynya untuk memastikan.
Menggunakan goto
juga menghasilkan kode yang lebih bersih dan langsung dengan logika kondisi-kemudian-lompat. Anda dapat melakukan hal berikut:
{
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.
Perhatikan label ditempatkan setelah penutupan }
. Ini adalah salah satu masalah yang mungkin terjadi goto
karena secara tidak sengaja menempatkan kode di antaranya karena Anda tidak melihat label. Sekarang seperti do{...}while(0)
tanpa kode kondisi.
Untuk membuat kode ini lebih bersih dan lebih mudah dipahami, Anda dapat melakukan ini:
//--------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)
Dengan ini, Anda dapat melakukan blok bersarang dan menentukan di mana Anda ingin keluar / melompat.
//--------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)
Kode spaghetti bukan kesalahan goto
, itu kesalahan programmer. Anda masih dapat menghasilkan kode spageti tanpa menggunakan goto
.