Đối với VC, đây là bài kiểm tra về khai báo chuyển tiếp và chỉ định loại cơ bản:
- đoạn mã sau được biên dịch ok.
typedef int myint;
enum T;
void foo (T * tp)
{
* tp = (T) 0x12345678;
}
enum T: char
{
Một
};
Nhưng nhận được cảnh báo cho / W4 (/ W3 không phát sinh cảnh báo này)
cảnh báo C4480: tiện ích mở rộng không chuẩn được sử dụng: chỉ định loại cơ bản cho enum 'T'
VC (Microsoft (R) Trình biên dịch tối ưu hóa C / C ++ 32 bit Phiên bản 15.00.30729.01 cho 80x86) có vẻ có lỗi trong trường hợp trên:
- khi thấy enum T; VC giả sử kiểu enum T sử dụng int 4 byte mặc định làm kiểu cơ bản, vì vậy mã lắp ráp được tạo là:
? foo @@ YAXPAW4T @@@ Z PROC; foo
; Tệp e: \ work \ c_cpp \ cpp_snippet.cpp
; Dòng 13
đẩy ebp
Mov ebp, đặc biệt
; Dòng 14
Mov eax, DWORD PTR _tp $ [ebp]
Mov DWORD PTR [eax], 305419896; 12345678H
; Dòng 15
pop ebp
giữ lại 0
? foo @@ YAXPAW4T @@@ Z ENDP; foo
Mã lắp ráp ở trên được trích xuất trực tiếp từ /Fatest.asm, không phải là phỏng đoán cá nhân của tôi. Bạn có thấy Mov DWORD PTR [eax], 305419896; Dòng 12345678H?
đoạn mã sau chứng minh điều đó:
int chính (int argc, char * argv)
{
liên hiệp {
char ca [4];
T t;
} 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]) ;
trả về 0;
}
kết quả là: 0x78, 0x56, 0x34, 0x12
- sau khi xóa khai báo chuyển tiếp của enum T và di chuyển định nghĩa của hàm foo sau định nghĩa của enum T: kết quả là OK:
hướng dẫn chính ở trên trở thành:
Mov BYTE PTR [eax], 120; 00000078H
kết quả cuối cùng là: 0x78, 0x1, 0x1, 0x1
Lưu ý rằng giá trị không bị ghi đè
Vì vậy, việc sử dụng khai báo chuyển tiếp của enum trong VC được coi là có hại.
BTW, để không ngạc nhiên, cú pháp khai báo kiểu cơ bản giống như trong C #. Trong pratice tôi thấy rằng đáng để lưu 3 byte bằng cách chỉ định loại cơ bản là char khi nói chuyện với hệ thống nhúng, bị giới hạn bộ nhớ.