Search code examples
delphirecorddelphi-10.3-rio

Why variable records reports bigger size that it should?


I tried this code:

  TDairyItemType = (dtFood, dtRecipe, dtExercise);
  TFourDecimalDWord = DWord;

  TDiaryItem = record
   ID: DWord;  // 4 bytes
   Positive: Boolean; // 1 byte
   GID: Word;  // 2 bytes
  case ItemType: TDairyItemType of  // 1 byte
   dtFood, dtRecipe: (ServID: Word; Serving: TFourDecimalDWord); // 6 bytes
   dtExercise: (Time: Word; Kcal: TFourDecimalDWord); // 6 bytes
  end;

procedure TForm1.Button1Click(Sender: TObject);
var Item: TDiaryItem;
begin
  Item.ServID:= 333;
  Caption:= 'Item size: '+IntToStr(SizeOf(TDiaryItem))+'  /  Item.Time: '+IntToStr(Item.Time);
end;

This shows me that the size of the record is 20, but it should be 14 because the last two lines of the record use the same space. I assigned a value to ServID field and I read it from Time field and it confirms that they share the same space... What am I missing ?


Solution

  • Alignment will add extra bytes. With packed to remove them it comes out as 14 bytes here.

    procedure TForm1.Button1Click(Sender: TObject);
    type
      TDairyItemType = (dtFood, dtRecipe, dtExercise);
      TFourDecimalDWord = DWord;
    
      TDiaryItem = packed record
       ID: DWord;  // 4 bytes
       Positive: Boolean; // 1 byte
       GID: Word;  // 2 bytes
      case ItemType: TDairyItemType of  // 1 byte
       dtFood, dtRecipe: (ServID: Word; Serving: TFourDecimalDWord); // 6 bytes
       dtExercise: (Time: Word; Kcal: TFourDecimalDWord); // 6 bytes
      end;
    
    begin
      button1.Caption:= 'Item size: '+IntToStr(SizeOf(TDiaryItem));
    end;