SizeOf для структур
 Добавлено: 04.09.2023 03:38:32
Добавлено: 04.09.2023 03:38:32- Код: Выделить всё
- TTestRecord = record
 id:Byte;
 Data:Byte;
 end;
SizeOf(TTestRecord) возвращает 2 - что логично и правильно
- Код: Выделить всё
- TTestRecord = record
 id:Byte;
 Data:Integer;
SizeOf(TTestRecord) возвращает 8 - как?? должно же быть 5!!
 
 Далее еще интереснее
- Код: Выделить всё
- TTestRecord = record
 id:Byte;
 Data:Int64;
SizeOf(TTestRecord) возвращает 16 - как?? должно же быть 9!!
 
   
 - Код: Выделить всё
- TTestRecord = record
 id:Byte;
 Data:Pointer;
SizeOf(TTestRecord) возвращает 16 - как??
 
   
   
 т.е. объявление тип Byte - в игнор, и выравниваем по самому большому размеру??
а как же тогда быть, если мне надо сохранить структуру в файл, где я хочу чтобы первое поле было все-таки 1 байт, а не целое в 4 байта или длинное целое в 8 байт!!
т.е. при сохранении в поток структуры, надо будет писать не outstrem.Write(data,SizeOf(TTestRecord))
а для каждого поля структуры отдельно
outstream.Write(data.id,sizeof(TTestRecord.id));
outstream.Write(data.data,sizeof(TTestRecord.data));
?? так конечно можно, но тогда какой смысл в структуре!? тогда изначально все хранить отдельно.....
 
 Как быть?? как записать данные структуры, так чтобы они записались в том количестве, которое как бы подразумевает определение типа, а не поведение компилятора?
и соответственно как их тогда обратно прочитать в структуру?
Добавлено спустя 15 минут 30 секунд:
- Код: Выделить всё
- TTestRecord = record
 id:Byte;
 case boolean of
 0 : (Buff:Array[1..5] of byte);
 1 : (Data:ShortInt);
 end;
при таком определении sizeOf выдает 6
и это правильно, но тут же
- Код: Выделить всё
- TTestRecord = record
 id:Byte;
 case boolean of
 0 : (Buff:Array[1..5] of byte);
 1 : (Data:Pointer);
 end;
лови размер структуры = 16 !!!
ничего не понимаю....
как быть уверенным в размерах выдаваемых sizeof и собственно тем что задано в описании типа?
Добавлено спустя 26 минут 41 секунду:
дальнейшие изыскания ставят в тупик еще больше
- Код: Выделить всё
- TTestShortArray = array of ShortInt;
 TTestIntegerArray = array of Integer;
 TTestLongIntArray = array of LongInt;
 TTestInt64Array = array of Int64;
 ....
 var
 p:Pointer;
 Begin
 GetMem(p,1024);
 Memo1.Lines.Append(IntToStr(SizeOf(TTestShortArray(p)[0])));
 Memo1.Lines.Append(IntToStr(SizeOf(TTestIntegerArray(p)[0])));
 Memo1.Lines.Append(IntToStr(SizeOf(TTestLongIntArray(p)[0])));
 Memo1.Lines.Append(IntToStr(SizeOf(TTestInt64Array(p)[0])));
Выдаст такую вот инфу:
1
4
4
8
т.е.
ShortInt стал = byte
Integer стал = LongInt
остальные вроде ожидаемо:
LongInt = LongInt
Int64 = Int64
Добавлено спустя 5 минут 58 секунд:
попробовал для разных ОС, для Линукс и Выньдовс - результаты одинаковы, т.е. хоть в чем-то проблемы нет
 
 при компиляции в другой ОСь, результат идентичен

Добавлено спустя 7 минут 17 секунд:
- Код: Выделить всё
- TTestShortArray(p)[0]:=256;
 Memo1.lines.Append(IntToStr(TTestShortArray(p)[0]));
выдаст 0 - что по размеру SizeOf - ожидаемо
и варнинг при комплияции unit1.pas(50,26) Warning: range check error while evaluating constants (256 must be between -128 and 127)
как так-то? почему shortInt 2 байта - стал byte ??