是否有阵列和压缩数组在德尔福有什么区别? [英] Are there any difference between array and packed array in Delphi?

查看:157
本文介绍了是否有阵列和压缩数组在德尔福有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C / C ++,你总是有

In C/C++ you always have

SizeOf(array[N] of T) = N * SizeOf(T);

在帕斯卡尔/德尔福可以使用打包阵,以确保上述断言是真实的,但'装'说明有德尔福阵列的任何实用价值?我无法创建'解包'阵列的一个例子,该阵列似乎总是包装:

In Pascal/Delphi you can use 'packed array' to be sure that the above assert is true, but does 'packed' specifier have any practical value for arrays in Delphi? I can't create an example of 'unpacked' array, the arrays seems always 'packed':

type
  A = array[0..2] of Byte;
  B = array[0..99] of A;
  C = packed record
    C1, C2, C3: Byte;
  end;
  D = array[0..99] of C;

procedure TForm10.Button1Click(Sender: TObject);
begin
  Assert(SizeOf(A) = 3);
  Assert(SizeOf(B) = 300);
  Assert(SizeOf(D) = 300);
end;

(该C / C ++结构和Delphi记录是不同 - 它们可以是解包,使该结构的大小大于字段的大小的总和,由于场的取向)。

(The C/C++ structures and Delphi records are different - they can be 'unpacked' so that the size of the structure is greater than the sum of field's sizes due to field's alignment).

推荐答案

它在Delphi中没有实际效果。唯一的类型可以合理影响是与最奇特取向和大小的组合的类型,扩展,其中有一个大小为10和8的对准然而,阵列扩展基本上包装已经(尽管他们仍然有8对齐;如果包装指令的工作就像是做了记录,他们将有1对齐)。

It has no practical effect in Delphi. The only type it could reasonably affect is the type with the oddest alignment and size combination, Extended, which has a size of 10 and an alignment of 8. However, arrays of Extended are essentially packed already (though they still have an alignment of 8; if the packed directive worked like it did on records, they would have an alignment of 1).

为什么我说的数组扩展是它可能会影响的唯一一种?有没有其他的德尔福类型,内置或者,你可以撰写,其中有一个大小不是其对齐的整数倍(撇开旧版本的Delphi,和一些bug)。对齐是使记录与填充更大的事;它会导致字段被隔开,使得每场开始于偏移这是它的类型的取向的整数倍。在类似的情况下以阵列,有仅涉及一种类型的,并且如果尺寸已经类型的取向的倍数,那么就没有必要填充

Why do I say arrays of Extended is the only type it could affect? There is no other Delphi type, built-in or that you can compose, which has a size that is not an integer multiple of its alignment (leaving aside older versions of Delp and some bugs). Alignment is the thing that makes records larger with padding; it causes fields to be spaced out so that every field starts at an offset which is an integer multiple of its type's alignment. In the analogous case with arrays, there is only one type involved, and if the size is already a multiple of the type's alignment, then there's no need for padding.

下面是一个程序,它显示了如何扩展会影响大小和对齐取决于它是包裹在一个记录或没有;您可以添加包装的阵列,并看到它没有什么区别:

Here's a program which shows how Extended affects size and alignment depending on whether it's wrapped in a record or not; you can add packed to the arrays, and see it makes no difference:

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.

有关调整更多的单词和包装包装有另一种效果(备案),而不是仅仅保证有是没有填充补充:它也标志着记录作为具有本身的1对准这具有导致它被频繁错位时,它的其他位置使用的负效应。为了进行语言/ OS互操作,只有在其他语言的不使用操作系统对齐规则(通常意味着Ç排列规则)的情况下,应在包装指令中使用。 (某些Windows API头有不正确的对齐方式在其中定义的类型,你要知道,和曾与它居住至今。)对于文件格式的目的兼容性,在另一方面,包装可能是合理的,但也有大量的其他问题有太多,就选择型(如整型随后是16位的Delphi 2个字节,但4个字节)。

More words about alignment and packed: packed has another effect (on records) rather than just guaranteeing that there is no padding added: it also marks the record as having itself an alignment of 1. This has the negative effect of causing it to be frequently misaligned when it is used elsewhere. For purposes of language / OS interoperability, only in the case where the other language is not using OS alignment rules (normally meaning C alignment rules) should the packed directive be used. (Some Windows API headers have incorrect alignment for types defined within them, mind you, and have had to live with it ever since.) For purposes of compatibility with a file format, on the other hand, packed may be justified, but there are lots of other concerns there too, with respect to type choice (e.g. Integer was 2 bytes in 16-bit Delp but 4 bytes subsequently).

德尔福尝试使用C兼容的规则排列。在过去,它有一些bug这里(特别是像TREC =记录A,B记录:外伸端;对TREC =记录中的一个:扩展; B:外伸端),但这些漏洞现在应该是固定

Delphi tries to use C-compatible rules for alignment. In the past, it had some bugs here (particularly with records like TRec = record A, B: Extended end; versus TRec = record A: Extended; B: Extended end;), but these bugs should be fixed now

这篇关于是否有阵列和压缩数组在德尔福有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆