1) английский я знаю плохо
2) если я правильно понял, сдесь обитает идин (несколько) из разработчиков FPC.
Собственно, Delphi-йский код, вычисляющий размер переменной типа Set of ... :
- Код: Выделить всё
type
TSomeType = char;// 20..32;
TDDD = set of TSomeType;
function SetOf_Size(): integer;
const
MASK_3 = $FF shl 3;
var
tpinfo: PTypeInfo;
TD: PtypeData;
begin
tpinfo := typeinfo(TDDD);
TD := GetTypeData(tpinfo);
TD := GetTypeData(TD.CompType^); // GetTypeData(TD.CompType) в FPC; Ошибка, кстати, здесь возникает.
with TD^ do
begin
Result := (((MaxValue+7+1)and MASK_3)-(MinValue and MASK_3))shr 3;
if (Result = 3) then Result := 4;
end;
end;
С чего хочу начать. Во-первых, я так и не понял, из каких соображений высчитывается sizeof(TDDD), можно ли где-то почитать ? ИМХО нужно было сделать как в Delphi, хотя бы в mode delphi - а то могут возникнуть серьёзные проблемы в чтении/записи файлов, например.
Во-вторых, TD.CompType: pptypeinfo в Delphi и ptypeinfo в FPC; но это не проблема.
Теперь переходим к ошибке. Как показали эксперименты, ошибка возникает в строчке GetTypeData(TD.CompType) в том случае, если ord(high(TSomeType)) > 31. Иначе говоря, если TSomeType - обычный небольшой enum (например: TSomeType = (_1, _2, _3)), то TD.CompType генерируется правильный. Если ord(high(TSomeType)) > 31, то TD.CompType указывает на какую-то левую область памяти (не nil), обращение к которой приводит к AccessViolation.
Буду рад, если:
1) проясните ситуация с sizeof()
2) ошибка исправится в следующих версиях компилятора
И напоследок, если можно задам пару вопросов по поводу TTypeKind.
Есть ли какое-то принципиальное отличие (в плане содержания и RTTI и обработки) между:
tkLString и tkAString, tkRecord и tkObject, tkInterface и tkInterfaceRaw ?
Заранее спасибо.