Nothing but "packed" records - should I fix this?

While looking at the code in our old Delphi 7 program, I noticed that everywhere there is an entry marked packed . This, of course, means that the record is stored byte-by-byte and does not align faster to access the CPU. It seems that the packaging was done blindly, like trying to outsmart the compiler or something in it - basically evaluating a few bytes of memory instead of faster access

Record Example:

 TFooTypeRec = packed record RID : Integer; Description : String; CalcInTotalIncome : Boolean; RequireAddress : Boolean; end; 

Should I fix this and make each record normal or not packed? Or is it negligible with modern processors and memory and probably a waste of time? Are there any problems that may result from unpacking?

+6
source share
4 answers

It is impossible to answer this question without a full understanding of how each of these packed entries is used in your application code. This is the same as the query "Should I change this variable declaration from Int64 to Byte?"

Not knowing what values ​​the variable will expect and which are necessary to maintain the response, may be yes. Or it may not be so.

Similarly in your case. If the record is to be packaged, it should be left packaged. If it does not need to be packaged, then there is no harm not to pack it. If you are not sure or cannot tell, then the safest course is to leave them as they are.

As a guide to making this decision (if you decide to continue), situations where packaging or recommended packaging is required include:

  • saving record values
  • sharing record values ​​with [potentially] compiled code in different ways
  • strict compatibility with external structures
  • intentionally overlaying a mock type on another structured memory

This is not necessarily an exhaustive list, and what do they have in common:

  • containing a series of values ​​in adjacent bytes that any potential producer or consumer of a record should and can rely on without the possibility of intervention by the compiler or other factors.

What I would recommend is that (if possible and practical) you determine what the purpose of the packaging is in each case, and add documentation to the recording announcement itself to this document so that everyone in the future with the same question needed to complete this discovery process, for example:

  type TSomeRecordType = packed record // This record must be packed as it is used for persistence .. end; TSomeExternType = packed record // This record must be packed as it is required to be compatible // in memory with an externally defined struct (ref: extern code docs) .. end; 
+21
source

The basic idea of ​​using packed records is not that you save a few bytes of memory! Instead, it is about ensuring that the variables are where you expect them to be in memory. Without such a guarantee, it would be impossible (or at least difficult) to manage memory manually on the heap, write and read from files.

Therefore, the program may not work correctly if you unzip the records!

+7
source

If a record is saved / retrieved as packaged or transferred in any way to a recipient who expects it to be packaged, do not modify it.

Update:

In your example, the type of string is specified. This looks suspicious, since saving a record in a binary file will not save the contents of the string.

+1
source
  • Packed records are exactly the same length as the members.
  • Optimized packed recording (they are aligned β†’ hence higher) for better performance.
0
source

Source: https://habr.com/ru/post/899081/


All Articles