W przypadku VC oto test dotyczący deklaracji forward i określenia typu bazowego:
- poniższy kod jest skompilowany ok.
typedef int myint;
wyliczyć T;
void foo (T * tp)
{
* tp = (T) 0x12345678;
}
enum T: char
{
ZA
};
Ale dostałem ostrzeżenie dla / W4 (/ W3 nie wyświetla tego ostrzeżenia)
ostrzeżenie C4480: używane niestandardowe rozszerzenie: określenie typu bazowego dla wyliczenia „T”
VC (Microsoft (R) 32-bitowy kompilator optymalizujący C / C ++ w wersji 15.00.30729.01 dla 80x86) wygląda wadliwie w powyższym przypadku:
- widząc enum T; VC zakłada, że typ wyliczeniowy T używa domyślnych 4 bajtów int jako typu bazowego, więc wygenerowany kod zestawu to:
? foo @@ YAXPAW4T @@@ Z PROC; bla
; Plik e: \ work \ c_cpp \ cpp_snippet.cpp
; Linia 13
push ebp
mov ebp, esp
; Linia 14
mov eax, DWORD PTR _tp $ [ebp]
mov DWORD PTR [eax], 305419896; 12345678H
; Linia 15
pop ebp
ret 0
? foo @@ YAXPAW4T @@@ Z ENDP; bla
Powyższy kod zestawu jest pobierany bezpośrednio z pliku /Fatest.asm, a nie w moich osobistych przypuszczeniach. Czy widzisz mov DWORD PTR [eax], 305419896; Linia 12345678H?
udowadnia to następujący fragment kodu:
int main (int argc, char * argv)
{
związek {
char ca [4];
T t;
}za;
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]) ;
zwraca 0;
}
wynikiem jest: 0x78, 0x56, 0x34, 0x12
- po usunięciu deklaracji do przodu enum T i przeniesieniu definicji funkcji foo po definicji enum T: wynik jest OK:
powyższa kluczowa instrukcja staje się:
mov BYTE PTR [eax], 120; 00000078H
końcowy wynik to: 0x78, 0x1, 0x1, 0x1
Uwaga: wartość nie jest nadpisywana
Tak więc zastosowanie deklaracji wyliczeniowej wyliczenia w VC jest uważane za szkodliwe.
BTW, żeby się nie dziwić, składnia deklaracji typu bazowego jest taka sama jak w C #. W praktyce stwierdziłem, że warto oszczędzić 3 bajty, określając typ podstawowy jako char podczas rozmowy z systemem osadzonym, który ma ograniczoną pamięć.