Странности с SizeOf

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Странности с SizeOf

Сообщение Troublemaker » 07.05.2008 09:26:51

Вот описание типов:

Код: Выделить всё
  T_Desc = string[50];
  T_Person = packed record //личность
    FIO,
    Rank:T_Desc
  end;
  T_CheckDate=packed record //Сведения о всяких проверках - утвердил, создал и т.п.
    Who:T_Person;  //кто проверял
    When:TDateTime;
    Desc:T_Desc;  //описание проверки
    REQ:Boolean;  //требуемое?
  end;
  T_ElementSignature=record
    case boolean of
    true: (SigTotal:array[1..4]of char);
    false: (SigHead,SigTail:array[1..2] of char);
  end;
//Типы элементов: коллекция, модули - теория и опрос, вопрос, ответ
  T_ElementType=(etCollection,etTheory,etExam,etQuestion,etAnswer);
  T_CommonElementData = packed record //общие данные для всех и вся
    ID:byte;   //мой номер
    MyType:T_ElementType;   //кто я по жизни
    Desc:T_Desc;
    SigHead,
    SigTail:T_ElementSignature;
    case T_ElementType of
      etCollection:(Placeholder:byte);
       etTheory,etExam,etQuestion,etAnswer:(ParentID:byte);  //папин номер (не используется для коллекции)
  end;
  T_CommonElementDates=packed record
    Created,  //создано
    Verified, //проверено
    Confirmed,  //утерждено
    LastModified:T_CheckDate;  //последние изменения
  end;
//виды коллекций: только теория,только опросы, смешанная
  T_CollectionKind=(ckTheory,ckExam,ckMixed);
   T_Collection=packed record  //коллекция
    ComData:T_CommonElementData;
    Dates:T_CommonElementDates;
    ValidSince,
    ValidUntil:TDateTime;  //даты годности коллекции - включительно.
    KindOf:T_CollectionKind;
  end;

Так вот на этом описании команда SizeOf(T_Collection) не работает (еще на этапе компиляции): Error: range check error while evaluating constants

Это как? Я впервые вижу такую диагностику.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Странности с SizeOf

Сообщение alexs » 07.05.2008 10:26:49

Код: Выделить всё
type
  T_Desc = string[50];
  T_Person = packed record //личность
    FIO,
    Rank:T_Desc
  end;
  T_CheckDate=packed record //Сведения о всяких проверках - утвердил, создал и т.п.
    Who:T_Person;  //кто проверял
    When:TDateTime;
    Desc:T_Desc;  //описание проверки
    REQ:Boolean;  //требуемое?
  end;
  T_ElementSignature=record
    case boolean of
    true: (SigTotal:array[1..4]of char);
    false: (SigHead,SigTail:array[1..2] of char);
  end;
//Типы элементов: коллекция, модули - теория и опрос, вопрос, ответ
  T_ElementType=(etCollection,etTheory,etExam,etQuestion,etAnswer);
  T_CommonElementData = packed record //общие данные для всех и вся
    ID:byte;   //мой номер
    MyType:T_ElementType;   //кто я по жизни
    Desc:T_Desc;
    SigHead,
    SigTail:T_ElementSignature;
    case T_ElementType of
      etCollection:(Placeholder:byte);
       etTheory,etExam,etQuestion,etAnswer:(ParentID:byte);  //папин номер (не используется для коллекции)
  end;
  T_CommonElementDates=packed record
    Created,  //создано
    Verified, //проверено
    Confirmed,  //утерждено
    LastModified:T_CheckDate;  //последние изменения
  end;
//виды коллекций: только теория,только опросы, смешанная
  T_CollectionKind=(ckTheory,ckExam,ckMixed);

   T_Collection=packed record  //коллекция
    ComData:T_CommonElementData;
    Dates:T_CommonElementDates;
    ValidSince,
    ValidUntil:TDateTime;  //даты годности коллекции - включительно.
    KindOf:T_CollectionKind;
  end;
begin
  writeln(SizeOf(T_Collection));
end.

Оформил твой код в программу. Всё скомпилировалось и запустилось:
Код: Выделить всё
C:\!\4>fpc aa.pas
Hint: End of reading config file C:\Lazarus\pp\bin\i386-win32\fpc.cfg
Free Pascal Compiler version 2.3.1 [2008/05/06] for i386
Copyright (c) 1993-2008 by Florian Klaempfl
Target OS: Win32 for i386
Compiling aa.pas
Linking aa.exe
48 lines compiled, 0.1 sec , 24816 bytes code, 1352 bytes data
2 hint(s) issued

C:\!\4>aa.exe
733
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

ВОПРОС СНЯТ

Сообщение Troublemaker » 07.05.2008 10:58:39

alexs писал(а):Оформил твой код в программу. Всё скомпилировалось и запустилось
Вот же я долбодятел! Переменная, в которую должен помещаться сайзоф - типа байт. Мой косяк, но пока не увидел твой результат - 733 - не доходило, в чем может быть дело.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Странности с SizeOf

Сообщение alexs » 07.05.2008 11:50:40

Troublemaker писал(а): packed record

Кстати - а зачем ты используешь упаковку? программа будет работать быстрее если ты разрешишь компилятору делать выравнивание. Или у тебя уже есть готовые файлы строго установленного формата?
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Странности с SizeOf

Сообщение Troublemaker » 07.05.2008 11:58:48

alexs писал(а):а зачем ты используешь упаковку?
Для уменьшения объема данных, ведь это будет писАться в файл(ы), которые будут как-то передаваться
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Странности с SizeOf

Сообщение alexs » 07.05.2008 12:20:15

на самом деле кардинально ты не уменьшиш этим - экономия будет максимум 3* кол-во полей (это если особо не повезёт)
и если не планируеш менять платформу - лучше использовать платформенно зависимые типы - integer и т.п.
но это конечно мелочи.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Странности с SizeOf

Сообщение Troublemaker » 07.05.2008 12:57:47

alexs писал(а):если не планируеш менять платформу - лучше использовать платформенно зависимые типы
Как раз и планирую, поэтому и пытаюсь писать с использованием Лазаря, чтобы можно было потом откомпилить и запустить и под виндой и под линуксом.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Странности с SizeOf

Сообщение alexs » 07.05.2008 13:16:08

я имел ввиду разрядность процесора
в пределах одной разрядности размеры данных в fpc одинаков и не зависит от платформы win/lin (поправьте меня, если я не прав)
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Странности с SizeOf

Сообщение Troublemaker » 07.05.2008 13:23:50

Если верить хелпу от D7, то действительно зависит не от платформы, а от процессора, причем от того, на котором выполняется компиляция.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Странности с SizeOf

Сообщение Vadim » 07.05.2008 13:56:58

Troublemaker
range check error - как раз и говорит о том, что произошла ошибка при проверке диапазона или, что тоже самое, значение вышло за допустимый диапазон (range).
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Странности с SizeOf

Сообщение Troublemaker » 07.05.2008 14:06:27

Vadim писал(а):range check error - говорит о том, что ... значение вышло за допустимый диапазон
Дык, это я в состоянии перевести, но пока не увидел, какое значение получается, не мог сообразить, о выходе за пределы КАКОГО-такого диапазона речь. Обычный "замыленный глаз", когда числовой переменной присваивается значение большее, чем разрешено для ее типа.
Мог, конечно, и сразу подумать о том, что четыре даты уже дадут больше 400 байт.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Странности с SizeOf

Сообщение alexs » 07.05.2008 14:24:00

Troublemaker писал(а):Если верить хелпу от D7, то действительно зависит не от платформы, а от процессора, причем от того, на котором выполняется компиляция

ну вобщето мы о fpc говорим :D я думаю, что тут будет зависеть от того для какого процесора компилим, а не на каком.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Странности с SizeOf

Сообщение shade » 08.05.2008 22:05:33

Troublemaker писал(а):Для уменьшения объема данных, ведь это будет писАться в файл(ы), которые будут как-то передаваться

Выравнивание можно в большинстые случаев с успехом обходить перестановкой полей.
Так например,
1. у нас в записи три Integer - ничего переставлять не надо, выравнивания не будет
2. у нас есть Integer и два byte и один word:
longint - 4 байта, смещение 0, кратно 4 - ok
word - 2 байта, смещение 4, кратно 2 - ok
byte - 1 байт, смещение 5, кратно 1 - ok
byte - 1 байт, смещение 6, кратной 1 - ok
- вы равнивания не будет
или другой вариант
word - 2 байта, смещение 0, кратно 2 - ok
byte - 1 байт, смещение 2, кратно 1 - ok
byte - 1 байт, смещение 3, кратно 1 - ok
longint - 1 байт, смещение 4, кратно 4 - ok

Можно предложить простое к применению правило: сортировать поля по их размеру - большие в начале, маленькие в конце.
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Re: Странности с SizeOf

Сообщение *vmr » 08.05.2008 22:45:58

alexs писал(а):Кстати - а зачем ты используешь упаковку? программа будет работать быстрее если ты разрешишь компилятору делать выравнивание. Или у тебя уже есть готовые файлы строго установленного формата?

Если это будет писатся в файлы, то упаковка обязательна, иначе можем получить разные результаты в зависимости от настроек выравнивания (4, 8, 16 байт) которые указываются черти-где и как попало :)
Аватара пользователя
*vmr
постоялец
 
Сообщения: 168
Зарегистрирован: 08.01.2007 01:46:07
Откуда: Киев


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru