Visual C++ cung cấp cả công tắc trình biên dịch (/Zp
) và pragma pack
để ảnh hưởng đến cấu trúc của các cấu trúc. Tuy nhiên, tôi dường như có một số quan niệm sai lầm về cách họ làm việc.Căn chỉnh cấu trúc trong Visual C++
Theo MSDN ứng với giá trị n liên kết nhất định,
sự liên kết của thành viên sẽ được trên một ranh giới đó là một trong hai bội của n hoặc bội số của kích thước của các thành viên, tùy theo là nhỏ hơn.
Giả sử giá trị gói là 8 byte (mặc định). Trong một cấu trúc, tôi nghĩ rằng bất kỳ thành viên nào có kích thước nhỏ hơn 8 byte sẽ có mức chênh lệch là bội số của kích thước của nó. Bất kỳ thành viên nào có kích thước từ 8 byte trở lên sẽ có mức chênh lệch là bội số của 8 byte.
Bây giờ uống theo chương trình sau:
#include <tchar.h>
#pragma pack(8)
struct Foo {
int i1;
int i2;
char c;
};
struct Bar {
char c;
Foo foo;
};
int _tmain(int argc, _TCHAR* argv[]) {
int fooSize = sizeof(Foo); // yields 12
Bar bar;
int fooOffset = ((int) &bar.foo) - ((int) &bar); // yields 4
return 0;
}
Cấu trúc Foo
là 12 byte trong kích thước. Vì vậy, trong phạm vi Bar
, tôi mong đợi các thành viên Foo
được bù đắp 8 (bội số của 8) trong khi thực sự nó ở bù đắp 4. Tại sao lại như vậy?
Ngoài ra, Foo
thực sự chỉ có 4 + 4 + 1 = 9 byte dữ liệu. Trình biên dịch tự động thêm byte đệm vào cuối. Nhưng một lần nữa, cho một giá trị liên kết 8 byte, không nên nó pad đến một bội số của 8 chứ không phải là 4?
Bất kỳ làm rõ nào được đánh giá cao!
Bạn có chắc 'int' của bạn chỉ là 4 byte không? Máy bạn đang chạy cái gì? –
@Tony: Đây là ứng dụng 32 bit. Nếu một int là 8 byte thay vì 4, một Foo với hai trong số đó không thể chỉ có 12 byte.:-) –