Для VC вот тест на предварительное объявление и определение базового типа:
- следующий код скомпилирован нормально
typedef int myint;
enum T;
void foo (T * tp)
{
* tp = (T) 0x12345678;
}
enum T: char
{
};
Но получил предупреждение для / W4 (/ W3 не несет это предупреждение)
предупреждение C4480: используется нестандартное расширение: указание базового типа для перечисления 'T'
VC (32-разрядный оптимизирующий компилятор C / C ++ версии 15.00.30729.01 для 80x86) выглядит некорректно в приведенном выше случае:
- при просмотре enum T; VC предполагает, что тип перечисления T использует 4 байта по умолчанию int как базовый тип, поэтому сгенерированный код сборки:
? foo @@ YAXPAW4T @@@ Z PROC; Foo
; Файл e: \ work \ c_cpp \ cpp_snippet.cpp
; Линия 13
толчок
мов ебп, эсп
; Линия 14
mov eax, DWORD PTR _tp $ [ebp]
mov DWORD PTR [eax], 305419896; 12345678H
; Строка 15
поп ебп
рет 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
Обратите внимание, что значение не перезаписывается
Поэтому использование форвард-декларации enum в VC считается вредным.
Кстати, не удивительно, что синтаксис для объявления базового типа такой же, как в C #. На практике я обнаружил, что стоит сэкономить 3 байта, указав базовый тип как char при обращении к встроенной системе, которая ограничена в памяти.