1. 背景
goto語句雖然目前已經不提倡使用,但是用起來還是很方便,尤其是老代碼中見的比較多。
在改動有goto語句的老代碼時需要特別注意,是否跳過來資源的釋放、有用變量的初始化等等。
很久之前寫c程序時,有些提交系統要求變量必須在函數開始地方全部申明,最近遇到了"crosses initialization of XXX"知道為什么了。就是因為有可能跳過變量的聲明。
2. 代碼例子
例子1:
1 #include <iostream> 2 class Test{ 3 public: 4 int a; 5 }; 6 7 int main(){ 8 Test t1; 9 std::cout << "ok" << std::endl; 10 goto _Lab1; 11 Test *t2 = new Test; //1 12 //Test t2; //2 13 _Lab1: 14 std::cout << t2->a << std::endl; //1 15 //std::cout << t2.a << std::endl; //2 16 return 0; 17 }
從代碼中也可以看出來,
(1) 在只打開第一種情況下,“goto _Lab1”跳過來t2變量的定義,導致t2沒有初始化。編譯報錯。
(2) 在只打開第二種情況下,由於Test類沒有顯示構造函數,編譯器會提供無參數的默認構造函數。編譯正常。執行后t2.a 是隨機的int值。
例子2:
1 #include <iostream> 2 class Test{ 3 public: 4 Test(int _a):a(_a){}; //提供顯示構造函數 5 int a; 6 }; 7 8 int main(){ 9 Test t1(1); 10 std::cout << "ok" << std::endl; 11 goto _Lab1; 12 Test t2(3); //沒有執行初始化 13 _Lab1: 14 std::cout << t2.a << std::endl; 15 return 0; 16 }
Test類顯示提供了帶參數構造函數后,t2由於goto語句導致未初始化,編譯失敗。