2013-08-10 39 views
6

, I đọc này: http://msdn.microsoft.com/en-us/library/83ythb65.aspx Nhưng không rõ ràng với tôi. Trước hết, __declspec(align(#)) làm cho mọi đối tượng (trong một cấu trúc) được khai báo với nó bắt đầu tại một offset được căn chỉnh. Phần đó rõ ràng. Các aligment cũng là 'kế thừa' bởi các cấu trúc các đối tượng được in Nhưng nó không thay đổi kích thước của đối tượng, phải không? Chính xác, tại sao sizeof() trong mã này:Công việc `__declspec (align (#))` hoạt động như thế nào?

__declspec(align(32)) struct aType {int a; int b;}; 
sizeof(aType); 

return 32?

Trả lời

12

Kích thước của đối tượng được sử dụng để tính toán độ lệch trong mảng và khi bạn sử dụng con trỏ, vì vậy sizeof(x) phải luôn là bội số của giá trị căn chỉnh. Trong trường hợp này, 1 x 32. Nhưng nếu bạn có __declspec(align(32)) struct aType {int a[12]; }; thì kích thước sẽ là 2 x 32 = 64, vì sizeof (a) là 12 x 4 = 48. Nếu chúng ta thay đổi nó để căn chỉnh thành 4, 8 hoặc 16, nó sẽ là 48.

Cách nó thực sự hoạt động là trình biên dịch thêm một thành viên đệm chưa được đặt tên sau các thành viên được đặt tên của cấu trúc, để lấp đầy cấu trúc theo kích thước căn chỉnh của nó.

Nếu nó không làm việc theo cách này, một cái gì đó như:

aType *aPtr = new aType[15]; 

aPtr[12].a = 42; 

sẽ không hoạt động đúng, vì trình biên dịch sẽ nhân lên 12 bởi sizeof(aPtr) để thêm vào aPtr nội bộ.

+0

Vì vậy, nó thực sự ** thay đổi ** kích thước của cấu trúc/đối tượng? – NPS

+2

Có, 'struct' hiện dài 32 byte. 8 byte cho hai số nguyên và 24 trong số các byte đó là "phụ" để lấp đầy khoảng trống giữa đối tượng aType đầu tiên và thứ hai trong một mảng, ví dụ. –

+0

Ok, nhưng tại sao lại ở đây: 'struct aType {int a; int b;}; typedef __declspec (align (32)) struct aType bType; 'nó chỉ thay đổi căn chỉnh và không phải kích thước ([MSDN] (http://msdn.microsoft.com/pl-pl/library/83ythb65.aspx)," Định nghĩa các kiểu mới với __declspec (align (#)) ")? – NPS

0

Tài liệu được viết kém hoặc lệnh tiếng Anh của tôi là tiếng nước ngoài không ngang bằng với nó.

// make a nice 16 align macro 
#ifndef ALIGN16 
#define ALIGN16 __declspec(align(16)) 
#endif 

// align the structure 
struct ALIGN16 CB { 
    ALIGN16 bool m1; // and 
    ALIGN16 int m2; // align 
    ALIGN16 int m3; // each 
    ALIGN16 short m4; // element 
}; 

// now it performs as expected 
printf("sizeof(CB) %d\r\n", sizeof(CB)); 
CB vCb; 
printf("CB: %p, %%%d\r\n", &vCb, (UINT_PTR)&vCb % 16); 
printf("CB.m1: %p, %%%d\r\n", &vCb.m1, (UINT_PTR)&vCb.m1 % 16); 
printf("CB.m2: %p, %%%d\r\n", &vCb.m2, (UINT_PTR)&vCb.m2 % 16); 
printf("CB.m3: %p, %%%d\r\n", &vCb.m3, (UINT_PTR)&vCb.m3 % 16); 
printf("CB.m4: %p, %%%d\r\n", &vCb.m4, (UINT_PTR)&vCb.m4 % 16); 

Các __declspec(align(#)) chỉ ảnh hưởng đến sự liên kết của cấu trúc và các sizeof(), KHÔNG mỗi thành viên trong đó. Nếu bạn muốn mỗi thuộc tính được căn chỉnh, bạn cần xác định căn chỉnh ở cấp thành viên.

Tôi cũng ban đầu giả định rằng struct-level __declspec(align()) ảnh hưởng đến nó và đó là thành viên nhưng không. Vì vậy, nếu bạn muốn căn chỉnh cho mỗi thành viên, bạn cần phải cụ thể.