Benarkah itu gotomelompati bit kode tanpa memanggil destruktor dan benda-benda?
misalnya
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
Tidak xakan bocor?
Benarkah itu gotomelompati bit kode tanpa memanggil destruktor dan benda-benda?
misalnya
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
Tidak xakan bocor?
"Won't x be leaked"maksudnya Jenis xadalah tipe data bawaan. Mengapa Anda tidak memilih contoh yang lebih baik?
goto, mereka berpikir bahwa bahkan variabel durasi penyimpanan otomatis entah bagaimana "bocor". Bahwa Anda dan saya tahu sebaliknya sama sekali tidak penting.
intbisa bocor, bisa juga bocor . Misalnya: void f(void) { new int(5); }kebocoran int.
Jawaban:
Peringatan: Jawaban ini berkaitan dengan C ++ hanya ; aturannya sangat berbeda di C.
Tidak
xakan bocor?
Tidak, sama sekali tidak.
Ini adalah mitos yang gotomerupakan beberapa konstruksi tingkat rendah yang memungkinkan Anda untuk mengganti mekanisme pelingkupan bawaan C ++. (Jika ada, itu longjmpmungkin rentan terhadap ini.)
Pertimbangkan mekanisme berikut yang mencegah Anda melakukan "hal buruk" dengan label (yang termasuk case label).
Anda tidak dapat melompati fungsi:
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
// error: label 'lol' used but not defined
[n3290: 6.1/1]:[..] Ruang lingkup label adalah fungsi di mana label itu muncul. [..]
Anda tidak dapat melompati inisialisasi objek:
int main() {
goto lol;
int x = 0;
lol:
return 0;
}
// error: jump to label ‘lol’
// error: from here
// error: crosses initialization of ‘int x’
Jika Anda melompat kembali melintasi inisialisasi objek, "instance" objek sebelumnya akan dimusnahkan :
struct T {
T() { cout << "*T"; }
~T() { cout << "~T"; }
};
int main() {
int x = 0;
lol:
T t;
if (x++ < 5)
goto lol;
}
// Output: *T~T*T~T*T~T*T~T*T~T*T~T
[n3290: 6.6/2]:[..] Transfer keluar dari loop, keluar dari blok, atau kembali melewati variabel yang diinisialisasi dengan durasi penyimpanan otomatis melibatkan penghancuran objek dengan durasi penyimpanan otomatis yang berada dalam lingkup pada titik yang ditransfer dari tetapi tidak pada titik yang ditransfer ke . [..]
Anda tidak dapat melompat ke dalam cakupan suatu objek, meskipun objek tersebut tidak dijalankan secara eksplisit:
int main() {
goto lol;
{
std::string x;
lol:
x = "";
}
}
// error: jump to label ‘lol’
// error: from here
// error: crosses initialization of ‘std::string x’
... kecuali untuk jenis objek tertentu , yang dapat ditangani oleh bahasa karena tidak memerlukan konstruksi "rumit":
int main() {
goto lol;
{
int x;
lol:
x = 0;
}
}
// OK
[n3290: 6.7/3]:Dimungkinkan untuk mentransfer ke dalam blok, tetapi tidak dengan cara yang mengabaikan deklarasi dengan inisialisasi. Sebuah program yang melompat dari titik di mana sebuah variabel dengan durasi penyimpanan otomatis tidak dalam cakupan ke titik di mana ia berada dalam ruang lingkup tidak terbentuk kecuali variabel tersebut memiliki tipe skalar, tipe kelas dengan konstruktor standar yang sepele dan destruktor sepele, a versi yang memenuhi syarat cv dari salah satu jenis ini, atau larik dari salah satu jenis sebelumnya dan dideklarasikan tanpa penginisialisasi. [..]
Demikian juga, objek dengan durasi penyimpanan otomatis yang tidak "bocor" ketika Anda gotokeluar dari ruang lingkup mereka :
struct T {
T() { cout << "*T"; }
~T() { cout << "~T"; }
};
int main() {
{
T t;
goto lol;
}
lol:
return 0;
}
// *T~T
[n3290: 6.6/2]:Saat keluar dari ruang lingkup (bagaimanapun tercapai), objek dengan durasi penyimpanan otomatis (3.7.3) yang telah dibangun dalam lingkup itu dihancurkan dalam urutan kebalikan dari konstruksi mereka. [..]
Mekanisme di atas memastikan bahwa gotoAnda tidak merusak bahasa.
Tentu saja, ini tidak secara otomatis berarti bahwa Anda "harus" menggunakan gotountuk setiap masalah tertentu, tetapi ini berarti bahwa masalah itu hampir tidak "jahat" seperti yang diyakini oleh mitos umum.