Delphiでは実際的な効果はありません。合理的に影響を与える可能性のある唯一のタイプは、アラインメントとサイズの組み合わせが最も奇妙なタイプでExtended
、サイズは10、アラインメントは8です。ただし、の配列Extended
は基本的にすでにパックされています(ただし、アラインメントは8のままです。packed
ディレクティブはレコードの場合と同じように機能し、1)の配置になります。
Extended
配列が影響を与える可能性がある唯一のタイプであると言うのはなぜですか?他のDelphiタイプ、組み込み、または作成できるものはありません。サイズは、その配置の整数倍ではありません(Delphiの古いバージョンといくつかのバグは別として)。アラインメントは、パディングによってレコードを大きくするものです。これにより、すべてのフィールドがそのタイプの配置の整数倍であるオフセットで開始するように、フィールドの間隔が空けられます。配列の類似のケースでは、関係するタイプは1つだけであり、サイズがすでにタイプの配置の倍数である場合は、パディングは必要ありません。
Extended
これは、レコードにラップされているかどうかに応じて、サイズと配置にどのように影響するかを示すプログラムです。packed
配列に追加して、違いがないことを確認できます。
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.
アラインメントとpacked
:についてのより多くの言葉packed
パディングが追加されていないことを保証するだけでなく、(レコードに対して)別の効果があります。レコード自体に1の位置合わせがあることもマークされます。これは、他の場所で使用すると、レコードが頻繁に位置ずれするという悪影響があります。言語/OSの相互運用性の目的で、他の言語がOSアラインメントルール(通常はCアラインメントルールを意味する)を使用していない場合にのみ、パックされたディレクティブを使用する必要があります。(一部のWindows APIヘッダーは、その中で定義された型に対して誤った配置になっています。それ以来、それを使用する必要があります。)一方、ファイル形式との互換性のために、packedは正当化される場合がありますが、タイプの選択に関しては、他にも多くの懸念事項があります(たとえば、整数は16ビットDelphiでは2バイトでしたが、その後は4バイトでした)。
Delphiは、アライメントにC互換のルールを使用しようとします。過去には、ここにいくつかのバグがありました(特に、TRec =レコードA、B:拡張終了、対TRec =レコードA:拡張、B:拡張終了などのレコード)が、これらのバグは今すぐ修正する必要があります