Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2009-11

Illegal type conversion errors in FPC 2.5.1

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Juha Manninen

Hello,

I managed to install the latest svn FPC and use it with Lazarus. Trying to compile VirtualTreeView component I get many errors about type conversions, like:

Error: Illegal type conversion: "Set Of TVTColumnOption" to "DWord" for line

    Dummy := LongWord(FOptions);

Error: Illegal type conversion: "DWord" to "Set Of TVTColumnOption" for line

      Result := TVTColumnOptions(LongWord(Value and $FFFF))

Seems that integers and sets can't be casted to each other any more. How to fix the problem?

Juha Manninen

Reply by email

Jonas Maebe
to Juha Manninen
Juha Manninen wrote
Seems that integers and sets can't be casted to each other any more.

No, the size of sets in Delphi and TP mode has been made Delphi/TP compatible by default, i.o.w.: {$packsets 1} is now the default for Delphi and TP mode. To convert a non-ordinal type to an ordinal type, the size of both types must be the same. In the past, the default set packing for all modes was 4, so all sets with < 33 elements had size 4.

If TVTColumnOption has less than 9 elements, the size of a set of TVTColumnOption will now be 1 in TP/Delphi mode; if it has between 9 and 16 elements, its size will be 2.

Jonas

Reply by email

Jonas Maebe
to Jonas Maebe
Jonas Maebe wrote
the size of sets in Delphi and TP mode has been made Delphi/TP compatible by default, i.o.w.: {$packsets 1}

Sorry, that should read {$packset 1}. And the remedy is to either change the typecast, or (and this is backward compatible) add {$packset 4} to the source.

Jonas

Reply by email

Jonas Maebe
Juha Manninen wrote 9 lines
In the latest Delphi VirtualTreeView version the typecast is changed to Byte or Word depending on the element count in a set. I decided to do the same thing. Then I realized the code doesn't work with FPC 2.2.4, so I added {$packset 1} or {$packset 2} directives. {$packset 1} if elementcount < 9. {$packset 2} if 8 < elementcount < 17. And I changed the typecasts accordingly to Byte or Word.

You can just add {$packset 1} once. It simply tells the compiler that the minimal size by which it can increment the size of sets is 1 byte (rather than the default 4 bytes). It does not mean that the compiler will try to store all sets in 1 byte.

What happens if (without $packset directives) a set has 17 elements? Does it use 3 or 4 bytes?

It will always be 4 bytes, even with {$packset 1}. Sets of 3 bytes do not exist in FPC nor Delphi, that's a special case (probably to make it easier to keep them in a register).

What if there are > 32 elements?

Then in the default case, the set will be 32 bytes. With {$packset x}, the size of the set will be rounded up to the nearest multiple of x that is large enough to hold all elements.

Show quoted text 6 lines
The casting here is used for streaming data, with Stream WriteBuffer and ReadBuffer. Is there any better way of doing this than casting to Byte, Word or LongWord and counting the elements?

Something like this:

type
   tsetarray = array[1..32] of byte;
   psetarray = ^tsetarray;
var
   i: longint;
begin
   for i:=1 to sizeof(setvar) do
     write(psetarray(@setvar)^[i])
end.

Reply by email

Jonas Maebe
to Jonas Maebe
Jonas Maebe wrote
You can just add {$packset 1} once. It simply tells the compiler that the minimal size by which it can increment the size of sets is 1 byte (rather than the default 4 bytes).

Well, the default is actually still different:
a) sets high(set)<32: 4 bytes
b) all other sets: 32 bytes

It can be activated after another {$packset x} directive using any of
the following:
{$packset fixed}
{$packset default}
{$packset normal}

Jonas

Reply by email