VC için, ileri bildirim ve temel türü belirleme testi:
- Aşağıdaki kod tamam derlendi.
int myint için typedef;
enum T;
geçersiz foo (T * tp)
{
* tp = (T) 0x12345678;
}
enum T: karakter
{
bir
};
Ancak / W4 için uyarı var (/ W3 bu uyarıyı içermiyor)
uyarı C4480: standart olmayan uzatma kullanıldı: enum 'T' için altta yatan türü belirtme
VC (Microsoft (R) 32-bit C / C ++ En İyileştirici Derleyici Sürümü 80x86 için 15.00.30729.01) yukarıdaki durumda buggy görünüyor:
- enum T'yi gördüğünüzde; VC, enum T türü varsayılan 4 bayt int'i altta yatan tür olarak kullandığını varsayar, bu nedenle oluşturulan derleme kodu:
? foo @ YAXPAW4T @@@ Z PROC; foo
; Dosya e: \ work \ c_cpp \ cpp_snippet.cpp
; Çizgi 13
itmek
mov ebp, esp
; Satır 14
mov eax, DWORD PTR _tp $ [ebp]
mov DWORD PTR [eax], 305419896; 12345678H
; Çizgi 15
pop ebp
ret 0
foo @@ YAXPAW4T @@@ Z ENDP; foo
Yukarıdaki montaj kodu /Fatest.asm dosyasından doğrudan çıkar, kişisel tahminim değil. Mov DWORD PTR [eax], 305419896; 12345678H hattı?
aşağıdaki kod pasajı bunu kanıtlar:
int main (int argc, char * argv)
{
Birlik {
char ca [4];
Tt;
} A;
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]) ;
dönüş 0;
}
sonuç: 0x78, 0x56, 0x34, 0x12
- enum T'nin ileri bildirimini kaldırın ve enum T'nin tanımından sonra işlev foo tanımını taşıyın: sonuç TAMAM:
Yukarıdaki anahtar talimat:
mov BYTE PTR [eax], 120; 00000078H
nihai sonuç: 0x78, 0x1, 0x1, 0x1
Değerin üzerine yazılmadığını unutmayın
Bu nedenle, VC'de enum ileri bildiriminin kullanılması zararlı olarak kabul edilir.
BTW, sürpriz olmamak üzere, altta yatan türün bildirimi için sözdizimi C # ile aynıdır. Uygulamada, bellek sınırlı olan gömülü sistemle konuşurken temel türü char olarak belirterek 3 bayt kaydetmeye değer buldum.