Question:
Why am I getting garbage returned from my record variables?
Answer:
This is most likely a problem with field alignment. If you are using an application in Delphi 5 that was migrated from an earlier version you should know that alignment changed in Delphi 5. See Delphi 5 help under
Contents | Upgrading to Delphi 5 | Compatibility issues | Default alignment.
If this is not your issue there is also a bug in Delphi 5 you should be aware of. If no compiler directive is specified the default is {$ALIGN ON} or simply {$A+}. Aligned means the record is unpacked and each field takes a fixed amount of space in memory based on the datatype. Packing is done to save memory.
The bug in Delphi can cause packing or inconsistent alignment to occur even when alignment is on, {$A+}. It occurs when multiple record fields are declared in the same line. Moreover, this alignment is not consistent, varying between 2, 4 and 6.
The solution is easy; declare each field in a new line. Here's an example that demonstrates the issue with Extended types. Since they are all Extended types they should all use the same amount of space in memory. Therefore the difference between each of the memory addresses should all be the same, but notice they are not. We've only observed this behavior with Extended and Real48 types. We've heard reports of it happening with other data types but have not been able to reproduce it.
procedure TForm1.Button1Click(Sender: TObject); var test1 : record field1, field2 : Extended; // Packed field3 : Extended; // Not packed field4 : Extended; // Not packed end; begin showmessage('Address of field1: ' + Inttostr(longint(@test1.field1)) + #10#13 + 'Address of field2: ' + IntTostr(longint(@test1.field2)) + #10#13 + 'Address of field3: ' + Inttostr(longint(@test1.field3)) + #10#13 + 'Address of field4: ' + IntTostr(longint(@test1.field4))); end;
Last Modified: 11-OCT-00