On the Delphi documentation issues

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.

  • The behavior change is related to C++ alignment compatibility changes in Delphi 2009
  • 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.

  • The packed keyword now forces byte alignment, whereas in the past it did not necessarily do this
  • 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 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
  • 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 ?

    Advertisements

    4 thoughts on “On the Delphi documentation issues

        • 100 % agree, the doc is confusing to say the least. When I first read about this in another document (which I’m unable to find at this moment), the impression I got was about alignment of the record itself. But that text was not really clear about the meaning, neither is the official documentation.

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s