gotoYıkıcıları ve nesneleri çağırmadan kod parçalarının üzerinden atladığı doğru mu?
Örneğin
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
Olmaz xsızdırılmış olabilir?
gotoYıkıcıları ve nesneleri çağırmadan kod parçalarının üzerinden atladığı doğru mu?
Örneğin
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
Olmaz xsızdırılmış olabilir?
"Won't x be leaked"geliyor? Türü, xyerleşik bir veri türüdür. Neden daha iyi bir örnek seçmiyorsun?
goto, otomatik depolama süresi değişkenlerinin bile bir şekilde "sızdırıldığını" düşünüyorlar. Senin ve benim bunun aksini bildiğimiz, tamamen konunun dışında.
intsızıntı edemez, bu olabilir sızdırılmış olması . Örneğin: void f(void) { new int(5); }bir int.
Yanıtlar:
Uyarı: Bu yanıt yalnızca C ++ ile ilgilidir ; C'de kurallar oldukça farklı.
Olmaz
xsızdırılmış olabilir?
Kesinlikle değil.
gotoC ++ 'ın yerleşik kapsam mekanizmalarını geçersiz kılmanıza izin veren bazı düşük seviyeli yapılar olan bir efsanedir . (Bir şey varsa, buna longjmpeğilimli olabilir.)
Etiketlerle ( caseetiketler dahil) "kötü şeyler" yapmanızı önleyen aşağıdaki mekanizmaları düşünün .
İşlevler arasında geçiş yapamazsınız:
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
// error: label 'lol' used but not defined
[n3290: 6.1/1]:[..] Bir etiketin kapsamı, içinde göründüğü işlevdir. [..]
Nesne ilklendirmesine atlayamazsınız:
int main() {
goto lol;
int x = 0;
lol:
return 0;
}
// error: jump to label ‘lol’
// error: from here
// error: crosses initialization of ‘int x’
Atlarsan geri nesne başlatma karşısında, daha sonra nesnenin önceki "örneği" yok edilir :
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]:[..] Bir döngüden, bir bloktan veya otomatik depolama süresi ile başlatılmış bir değişkeni geri geçerek transfer, transfer edilen ancak transfer edilen noktada olmayan noktada kapsam içinde olan otomatik depolama süresi olan nesnelerin yok edilmesini içerir . [..]
Açıkça başlatılmamış olsa bile bir nesnenin kapsamına atlayamazsınız:
int main() {
goto lol;
{
std::string x;
lol:
x = "";
}
}
// error: jump to label ‘lol’
// error: from here
// error: crosses initialization of ‘std::string x’
... "karmaşık" yapı gerektirmedikleri için dilin üstesinden gelebileceği belirli nesne türleri dışında
int main() {
goto lol;
{
int x;
lol:
x = 0;
}
}
// OK
[n3290: 6.7/3]:Bir bloğa transfer etmek mümkündür, ancak başlatma ile bildirimleri atlayacak şekilde değil. Otomatik depolama süresi olan bir değişkenin kapsam içinde olmadığı bir noktadan, değişken skaler tip, önemsiz bir varsayılan kurucuya sahip sınıf tipi ve önemsiz bir yıkıcıya sahip olmadığı sürece kötü biçimlendirilmiş bir noktaya sıçrayan bir program, a Bu türlerden birinin cv nitelikli sürümü veya önceki türlerden birinin dizisi ve bir başlatıcı olmadan bildirilir. [..]
Aynı şekilde, otomatik depolama süresi nesneler vardır değil "sızan" sizi gotodışarı onların kapsamı :
struct T {
T() { cout << "*T"; }
~T() { cout << "~T"; }
};
int main() {
{
T t;
goto lol;
}
lol:
return 0;
}
// *T~T
[n3290: 6.6/2]:Bir kapsamdan çıkıldığında (ne kadar başarılı olursa olsun), o kapsamda inşa edilen otomatik depolama süresine (3.7.3) sahip nesneler, yapımlarının tersi sırada imha edilir. [..]
Yukarıdaki mekanizmalar gotobunun dili kırmanıza izin vermemesini sağlar.
Tabii ki, bu otomatik olarak anlamına gelmez sen kullanımı "gereken" gotoHerhangi bir sorunun, ancak does neredeyse inanmak ortak efsane açar insanlar olarak "kötü" olarak olmadığını ortalama.