No tiene ningún efecto práctico en Delphi. El único tipo al que podría afectar razonablemente es el tipo con la combinación más extraña de alineación y tamaño, Extended
, que tiene un tamaño de 10 y una alineación de 8. Sin embargo, las matrices de Extended
están esencialmente empaquetadas (aunque todavía tienen una alineación de 8 ; si la directiva packed
funcionara como lo hizo en los registros, tendrían una alineación de 1).
¿Por qué digo arreglos de Extended
es el único tipo que podría afectar? No hay otro tipo de Delphi, integrado o que pueda componer, que tiene un tamaño que no es un múltiplo entero de su alineación (dejando de lado las versiones anteriores de Delphi y algunos errores). La alineación es lo que hace que los registros sean más grandes con relleno; hace que los campos se espacien para que cada campo comience en un desplazamiento que es un múltiplo entero de la alineación de su tipo. En el caso análogo con arreglos, solo hay un tipo involucrado, y si el tamaño ya es un múltiplo de la alineación del tipo, entonces no hay necesidad de relleno.
Aquí hay un programa que muestra cómo Extended
afecta el tamaño y la alineación dependiendo de si está envuelto en un registro o no; puede agregar packed
a las matrices, y ver que no hay diferencia:
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.
Más palabras sobre la alineación y packed
: packed
tiene otro efecto (en registros) en lugar de sólo garantiza que no hay ningún relleno añadido: también marca que el registro tiene una alineación de 1. Esto tiene el efecto negativo de causar que se desalinee con frecuencia cuando se usa en otro lugar. A efectos de la interoperabilidad del lenguaje/sistema operativo, solo en el caso en que el otro idioma no esté utilizando las reglas de alineación del sistema operativo (que normalmente significan reglas de alineación C), debe usarse la directiva empaquetada. (Algunos encabezados de la API de Windows tienen una alineación incorrecta para los tipos definidos dentro de ellos, claro, y han tenido que vivir con eso desde entonces.) Por razones de compatibilidad con un formato de archivo, por otro lado, empaquetado puede estar justificado, pero hay muchas otras preocupaciones también, con respecto a la elección de tipo (por ejemplo, Integer tenía 2 bytes en Delphi de 16 bits, pero 4 bytes posteriormente).
Delphi intenta usar reglas compatibles con C para la alineación. En el pasado, tenía algunos errores aquí (particularmente con registros como TRec = registro A, B: extremo extendido, versus TRec = registro A: extendido; B: extremo extendido;), pero estos errores deberían corregirse ahora
Supongo que sin el modificador 'packed' futuras versiones del compilador delphi pueden usar matrices no compactas. Personalmente utilizo 'packed' si y solo si me importa el diseño de memoria exacto. – CodesInChaos