Nó không có hiệu quả thực tế trong Delphi. Loại duy nhất nó có thể ảnh hưởng một cách hợp lý là loại có sự liên kết và kích thước nhỏ nhất, Extended
, có kích thước 10 và căn chỉnh 8. Tuy nhiên, các mảng Extended
về cơ bản đã được đóng gói (mặc dù chúng vẫn có liên kết 8 ; nếu chỉ thị packed
hoạt động như đã thực hiện trên hồ sơ, họ sẽ có căn chỉnh 1).
Tại sao tôi nói mảng Extended
là loại duy nhất nó có thể ảnh hưởng? Không có loại Delphi khác, được xây dựng trong hoặc bạn có thể soạn, có kích thước không phải là một bội số nguyên của sự liên kết của nó (để lại một số phiên bản cũ hơn của Delphi và một số lỗi). Căn chỉnh là thứ làm cho các bản ghi lớn hơn với đệm; nó làm cho các trường được đặt cách nhau sao cho mỗi trường bắt đầu tại một offset, là bội số nguyên của sự liên kết kiểu của nó. Trong trường hợp tương tự với mảng, chỉ có một loại có liên quan, và nếu kích thước đã là bội số của sự liên kết của loại, thì không cần phải đệm.
Đây là chương trình hiển thị cách Extended
ảnh hưởng đến kích thước và căn chỉnh tùy thuộc vào việc nó được bao bọc trong bản ghi hay không; bạn có thể thêm packed
đến mảng, và xem nó làm cho không có sự khác biệt:
type
TWrap = record
X: Extended;
end; // field size=10, align=8, => actual size=16
TArr1 = array[1..3] of TWrap; // 3*16 => size=48, align=8
TArr2 = array[1..3] of Extended; // 3 * 10 => size=30, align=8
TRec1 = record
A: Byte;
B: TArr1;
end;
TRec2 = record
A: Byte;
B: TArr2;
end;
var
x: TRec1;
y: TRec2;
begin
Writeln('Size of TArr1: ', SizeOf(TArr1));
Writeln('Alignment of TArr1: ', Integer(@x.B) - Integer(@x.A));
Writeln('Size of TArr2: ', SizeOf(TArr2));
Writeln('Alignment of TArr2: ', Integer(@y.B) - Integer(@y.A));
end.
More lời về sự liên kết và packed
: packed
có một hiệu ứng (trên hồ sơ) thay vì chỉ đảm bảo rằng không có đệm thêm: nó cũng đánh dấu các bản ghi là có chính nó một sự liên kết của 1. Điều này có tác động tiêu cực gây ra nó thường xuyên bị lệch hướng khi nó được sử dụng ở nơi khác. Vì mục đích của khả năng tương tác ngôn ngữ/hệ điều hành, chỉ trong trường hợp ngôn ngữ khác không sử dụng quy tắc căn chỉnh OS (thường có nghĩa là quy tắc căn chỉnh C) nên chỉ thị đóng gói được sử dụng. (Một số tiêu đề Windows API có sự liên kết không đúng đối với các kiểu được định nghĩa bên trong chúng, hãy nhớ bạn và phải sống với nó từ đó.) Vì mục đích tương thích với định dạng tệp, mặt khác, được đóng gói có thể hợp lý, nhưng có rất nhiều mối quan tâm khác có quá, đối với loại lựa chọn (ví dụ như Integer là 2 byte trong 16-bit Delphi, nhưng 4 byte sau đó).
Delphi cố gắng sử dụng các quy tắc tương thích với C để căn chỉnh. Trong quá khứ, nó có một số lỗi ở đây (đặc biệt là với các bản ghi như TRec = bản ghi A, B: Mở rộng kết thúc; so với TRec = bản ghi A: Mở rộng; B: Mở rộng kết thúc;), nhưng các lỗi này phải được sửa ngay bây giờ
Tôi đoán không có phiên bản bổ sung 'đóng gói' trong tương lai của trình biên dịch delphi có thể sử dụng các mảng không nhỏ gọn. Cá nhân tôi sử dụng 'đóng gói' nếu và chỉ khi tôi quan tâm đến bố cục bộ nhớ chính xác. – CodesInChaos