Untuk VC, inilah ujian tentang penerusan deklarasi dan menentukan tipe yang mendasarinya:
- kode berikut dikompilasi ok.
ketikkan int myint;
enum T;
batal foo (T * tp)
{
* tp = (T) 0x12345678;
}
enum T: char
{
SEBUAH
};
Tetapi mendapat peringatan untuk / W4 (/ W3 tidak dikenakan peringatan ini)
peringatan C4480: ekstensi tidak standar yang digunakan: menentukan tipe yang mendasari untuk enum 'T'
VC (Microsoft (R) 32-bit C / C ++ Mengoptimalkan Versi Kompiler 15.00.30729.01 untuk 80x86) terlihat bermasalah dalam kasus di atas:
- saat melihat enum T; VC mengasumsikan enum tipe T menggunakan int standar 4 byte sebagai tipe yang mendasarinya, sehingga kode perakitan yang dihasilkan adalah:
? foo @@ YAXPAW4T @@@ Z PROC; foo
; File e: \ work \ c_cpp \ cpp_snippet.cpp
; Baris 13
tekan ebp
mov ebp, esp
; Baris 14
mov eax, DWORD PTR _tp $ [ebp]
mov DWORD PTR [eax], 305419896; 12345678H
; Baris 15
pop ebp
ret 0
? foo @@ YAXPAW4T @@@ Z ENDP; foo
Kode rakitan di atas diekstraksi dari /Fatest.asm secara langsung, bukan tebakan pribadi saya. Apakah Anda melihat mov DWORD PTR [eax], 305419896; Baris 12345678H?
cuplikan kode berikut membuktikannya:
int main (int argc, char * argv)
{
Persatuan {
char ca [4];
Tt;
}Sebuah;
a.ca [0] = a.ca [1] = a. [ca [2] = a.ca [3] = 1;
foo (& a.t);
printf ("% # x,% # x,% # x,% # x \ n", a.ca [0], a.ca [1], a.ca [2], a.ca [3]) ;
return 0;
}
hasilnya adalah: 0x78, 0x56, 0x34, 0x12
- setelah menghapus deklarasi maju enum T dan pindahkan definisi fungsi foo setelah definisi enum T: hasilnya OK:
instruksi kunci di atas menjadi:
mov BYTE PTR [eax], 120; 00000078H
hasil akhirnya adalah: 0x78, 0x1, 0x1, 0x1
Perhatikan nilainya tidak ditimpa
Jadi penggunaan maju-deklarasi enum di VC dianggap berbahaya.
BTW, tidak mengherankan, sintaks untuk deklarasi tipe yang mendasarinya sama dengan di C #. Dalam praktiknya saya menemukan itu layak untuk menyimpan 3 byte dengan menentukan tipe yang mendasarinya sebagai char ketika berbicara dengan sistem tertanam, yang merupakan memori terbatas.