TL; DR
Satu-satunya cara Anda dapat mendeklarasikan variabel dengan intializer atau objek non-sepele di dalam kasus adalah dengan memperkenalkan cakupan blok menggunakan {}
atau struktur kontrol lain yang memiliki ruang lingkup sendiri seperti loop atau pernyataan if .
Detail berdarah
Kita dapat melihat bahwa kasus hanyalah pernyataan berlabel seperti label yang digunakan dengan pernyataan goto ( ini tercakup dalam standar draf C ++ bagian 6.1 Pernyataan berlabel ) dan kita dapat melihat dari bagian 6.7
paragraf 3 bahwa melompati deklarasi tidak diperbolehkan dalam banyak kasus , termasuk yang memiliki inisialisasi:
Dimungkinkan untuk mentransfer ke dalam blok, tetapi tidak dengan cara yang mengabaikan deklarasi dengan inisialisasi. Sebuah program yang melompat 87 dari titik di mana sebuah variabel dengan durasi penyimpanan otomatis tidak dalam ruang lingkup ke titik di mana ia berada dalam ruang lingkup tidak terbentuk kecuali variabel tersebut memiliki tipe skalar, tipe kelas dengan konstruktor standar sepele dan destruktor sepele, versi yang memenuhi syarat cv dari salah satu jenis ini, atau larik dari salah satu jenis sebelumnya dan dideklarasikan tanpa penginisialisasi (8.5).
dan memberikan contoh ini:
void f() {
// ...
goto lx; // ill-formed: jump into scope of a
ly:
X a = 1;
// ...
lx:
goto ly; // OK, jump implies destructor
// call for a followed by construction
// again immediately following label ly
}
Perhatikan, ada beberapa kehalusan di sini, Anda diizinkan untuk melewati deklarasi skalar yang tidak memiliki inisialisasi, misalnya:
switch( n )
{
int x ;
//int x = 10 ;
case 0:
x = 0 ;
break;
case 1:
x = 1 ;
break;
default:
x = 100 ;
break ;
}
benar-benar valid ( contoh langsung ). Tentu saja jika Anda ingin mendeklarasikan variabel yang sama dalam setiap kasus maka mereka masing-masing akan membutuhkan ruang lingkupnya sendiri tetapi bekerja dengan cara yang sama di luar pernyataan switch juga, jadi itu seharusnya tidak menjadi kejutan besar.
Adapun alasan untuk tidak mengizinkan inisialisasi lompatan melewati, laporan kerusakan 467 meskipun mencakup masalah yang sedikit berbeda memberikan kasus yang wajar untuk variabel otomatis :
[...] variabel otomatis, jika tidak diinisialisasi secara eksplisit, dapat memiliki nilai tak tentu ("sampah"), termasuk representasi perangkap, [...]
Mungkin lebih menarik untuk melihat kasus di mana Anda memperluas cakupan dalam sebuah sakelar ke beberapa kasus. Contoh paling terkenal dari ini mungkin adalah perangkat Duff yang akan terlihat seperti ini:
void send( int *to, const int *from, int count)
{
int n = (count + 7) / 8;
switch(count % 8)
{
case 0: do { *to = *from++; // <- Scope start
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while(--n > 0); // <- Scope end
}
}