Для VC ось тест щодо прямого декларування та визначення базового типу:
- наступний код складається добре.
typedef int myint;
перерахунок Т;
пустоту (T * tp)
{
* tp = (T) 0x12345678;
}
перерахунок T: char
{
А
};
Але я отримав попередження для / W4 (/ W3 не несе цього попередження)
попередження C4480: нестандартне розширення, що використовується: визначення базового типу для enum 'T'
32-розрядний C / C ++ оптимізаційний компілятор VC (Microsoft (R) для версії 15.00.30729.01 для 80x86) виглядає непогашеним у наведеному вище випадку:
- коли бачимо перерахунок T; VC передбачає, що тип enum T використовує типовий 4 байт int як базовий тип, тож сформований код складання:
? foo @@ YAXPAW4T @@@ Z PROC; foo
; Файл e: \ work \ c_cpp \ cpp_snippet.cpp
; Рядок 13
поштовх
mov ebp, esp
; Рядок 14
mov eax, DWORD PTR _tp $ [ebp]
mov DWORD PTR [eax], 305419896; 12345678H
; Рядок 15
pop ebp
ret 0
? foo @@ YAXPAW4T @@@ Z ENDP; foo
Вищевказаний код складання витягується безпосередньо з /Fatest.asm, а не моя особиста здогадка. Чи бачите ви mov DWORD PTR [eax], 305419896; 12345678H лінія?
наступний фрагмент коду доводить це:
int main (int argc, char * argv)
{
союз {
char ca [4];
Т т;
} а;
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]) ;
повернути 0;
}
результат: 0x78, 0x56, 0x34, 0x12
- після видалення прямого оголошення enum T і перемістіть визначення функції foo після визначення enum T: результат ОК:
наведена вище ключова інструкція стає:
mov BYTE PTR [eax], 120; 00000078H
кінцевий результат: 0x78, 0x1, 0x1, 0x1
Зверніть увагу, що значення не перезаписується
Тож використання попереднього оголошення перерахунку у ВК вважається шкідливим.
BTW, щоб не дивувати, синтаксис для декларування базового типу такий же, як його у C #. У практиці я виявив, що варто зберегти 3 байти, вказавши базовий тип char, коли говорити з вбудованою системою, яка обмежена пам'яттю.