Delphi XE2 documentation states:
‘Packed’ Now Forces Byte Alignment of Records
If you have legacy code that uses the packed record type and you want to link with an external DLL or with C++, you need to remove the word “packed” from your code. The packed keyword now forces byte alignment, whereas in the past it did not necessarily do this. The behavior change is related to C++ alignment compatibility changes in Delphi 2009.
The above cannot be classified even as a documentation bug; it is just a nonsense. There was a related StackOverflow question. The question remained unanswered because it is impossible to answer it reasonably. Now more than a month passed, and the documentation issue is still there – the documentation writers definitely don’t read SO.
The best reading about Delphi alignment rules that I know is the Barry Kelly answer on SO.
Let us try to analyze what the documentation is about.
Delphi 2009 fixed a bug that caused different layout for
type TRec = record A, B: Extended; end;
and
type TRec = record A: Extended; B: Extended; end;
records in the previous versions, and introduced {$OLDTYPELAYOUT ON} directive to reproduce the alignment bug for compatibility reasons.
Hard to explain how that is related to ‘Packed’ Now Forces Byte Alignment of Records.
Seems like nobody can say now what the past the documentation writer is talking about. Maybe ages ago first Turbo Pascal versions treated external type alignment and internal record layout differently. Or maybe where was some bug in packed specifier implementation that nobody was ever aware of, and the bug was fixed ages ago – one can only guess.
If so, what is the Delphi equivalent of #pragma pack(1) in C/C++? Maybe the documentation writer suggests to use {$A1} or {$A-} directives instead of packed specifier? But {$A1}, {$A-} directives and packed specifier do exactly the same thing – force byte alignment. There is no difference here. Or maybe #pragma pack(1) in C/C++ affects only internal structure layout and not structure alignment?
Just to be sure I have tested the following code sample in Visual Studio 2010:
struct S { short j; // size 2 double k; // size 8 }; #pragma pack(1) // force byte alignment struct T { short j; double k; }; #pragma pack() // restore default alignment struct S1{ char cc; // size 1 S ss; // size 16 }; struct T1{ char cc; // size 1 T tt; // size 10 }; int _tmain(int argc, _TCHAR* argv[]) { printf("%d %d\n", sizeof(S), offsetof(S, k)); // 16 8 printf("%d %d\n", sizeof(T), offsetof(T, k)); // 10 2 printf("%d %d\n", sizeof(S1), offsetof(S1, ss)); // 24 8 printf("%d %d\n", sizeof(T1), offsetof(T1, tt)); // 11 1 _getch(); return 0; }
As you can see #pragma pack(1) forces byte alignment for both T structure fields and T structure as a whole, exactly the same thing as packed specifier in Delphi do.
So what the documentation writer is talking about ?