Sign in Join

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

Mailing lists / fpc-devel / 2012-09

enums and integer auto conversion

17 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

Den Jean

Hi,

As described in
http://bugs.freepascal.org/view.php?id=22797

fpc 2.7.1 does not allow anymore to pass an enum
to a function expecting integers.

Note that there has always been a
{$MINENUMSIZE 4} in qt4.pas

Is this intended behaviour ? I really hope it is not.

I cannot define the type of the parameter
as the enumtype because the expected values
are either the enum or combinations of the enum (or)

Kind regards,

Den Jean

Reply by email

Vincent Snijders
to Den Jean

2012/9/10 Den Jean :

Show quoted text 16 lines
Hi, As described in http://bugs.freepascal.org/view.php?id=22797 fpc 2.7.1 does not allow anymore to pass an enum to a function expecting integers. Note that there has always been a {$MINENUMSIZE 4} in qt4.pas Is this intended behaviour ? I really hope it is not. I cannot define the type of the parameter as the enumtype because the expected values are either the enum or combinations of the enum (or)

If it is the combination of enum, then the type of the parameter is set of enum.

Vincent

Reply by email

Den Jean
to Vincent Snijders
Vincent Snijders wrote
If it is the combination of enum, then the type of the parameter is set of enum.

Ahum, I am talking about passing combinations of enums values (usually bitmasks, assigned enums, some assigned enums are already combinations of other) to C or C++.
Sets are not binary compatible for that.

Reply by email

Daniël Mantione
to Den Jean

Op Mon, 10 Sep 2012, schreef Den Jean:

Show quoted text 7 lines
On Monday 10 September 2012 20:18:52 Vincent Snijders wrote: > If it is the combination of enum, then the type of the parameter is set of > enum. Ahum, I am talking about passing combinations of enums values (usually bitmasks, assigned enums, some assigned enums are already combinations of other) to C or C++. Sets are not binary compatible for that.

They should be.

Daniël

Reply by email

Marco van de Voort
to Daniël Mantione

In our previous episode, Dani?l Mantione said:

Show quoted text 9 lines
> On Monday 10 September 2012 20:18:52 Vincent Snijders wrote: >> If it is the combination of enum, then the type of the parameter is set of >> enum. > Ahum, I am talking about passing combinations of enums values > (usually bitmasks, assigned enums, some assigned enums > are already combinations of other) to C or C++. > Sets are not binary compatible for that. They should be.

Afaik {$mode delphi} doesn't auto enable the equivalent packenum/set. I noticed that last week too.

Reply by email

Jonas Maebe
to Daniël Mantione: Op Mon, 10 Sep 2012, schreef Den Jean: They should be. Daniël
Daniël Mantione wrote 9 lines
> On Monday 10 September 2012 20:18:52 Vincent Snijders wrote: >> If it is the combination of enum, then the type of the parameter is set of >> enum. > Ahum, I am talking about passing combinations of enums values > (usually bitmasks, assigned enums, some assigned enums > are already combinations of other) to C or C++. > Sets are not binary compatible for that. They should be.

No, sets are an opaque data type. Their internal format is undefined.

Jonas

Reply by email

Jonas Maebe
to Den Jean: As described in http://bugs.freepascal.org/view.php?id=22797 fpc 2.7.1 does not allow…
Den Jean wrote 5 lines
As described in http://bugs.freepascal.org/view.php?id=22797 fpc 2.7.1 does not allow anymore to pass an enum to a function expecting integers.

This has never been allowed. The only thing that was allowed was defining an enum as a default value for integer parameters. But then again, you could also define a char, a floating point value, a string, or really anything as default value for any kind of parameter. The compiler was simply missing any kind of type checking for the default value.

Note that there has always been a {$MINENUMSIZE 4} in qt4.pas

That defines the size, not the type.

Is this intended behaviour ? I really hope it is not.

It is.

I cannot define the type of the parameter as the enumtype because the expected values are either the enum or combinations of the enum (or)

As mentioned above, that never worked in the past either.

Jonas

Reply by email

Daniël Mantione
to Jonas Maebe: No, sets are an opaque data type. Their internal format is undefined. Jonas

Op Mon, 10 Sep 2012, schreef Jonas Maebe:

Show quoted text 14 lines
On 10 Sep 2012, at 22:06, Daniël Mantione wrote: >> On Monday 10 September 2012 20:18:52 Vincent Snijders wrote: >>> If it is the combination of enum, then the type of the parameter is set of >>> enum. >> Ahum, I am talking about passing combinations of enums values >> (usually bitmasks, assigned enums, some assigned enums >> are already combinations of other) to C or C++. >> Sets are not binary compatible for that. > > They should be. No, sets are an opaque data type. Their internal format is undefined.

I knew you would answer to that :) While, I disagree that a set is opaque, but, we can skip that discussion. What's going on here is that, wether it is a good idea or not, the implementor of the QT interface units is trying to provide Pascal data types to its user. Given the fact you are doing that, a set of enum is IMO as reasonable as other weak type to strong type mappings.

Daniël

Reply by email

Jonas Maebe
to Daniël Mantione
Daniël Mantione wrote 5 lines
Op Mon, 10 Sep 2012, schreef Jonas Maebe: > No, sets are an opaque data type. Their internal format is undefined. I knew you would answer to that :) While, I disagree that a set is opaque, but, we can skip that discussion. What's going on here is that, wether it is a good idea or not, the implementor of the QT interface units is trying to provide Pascal data types to its user. Given the fact you are doing that, a set of enum is IMO as reasonable as other weak type to strong type mappings.

If you want to do that, you need to add a layer in between that converts the sets into integer bitmasks in a reliable, portable and future-proof way.

Jonas

Reply by email

Daniël Mantione
to Jonas Maebe

Op Mon, 10 Sep 2012, schreef Jonas Maebe:

If you want to do that, you need to add a layer in between that converts the sets into integer bitmasks in a reliable, portable and future-proof way.

Yes! Let's also convert integers to enums with a case statement rather than typecast, just in case the compiler may not count enums from zero in the future ;)

Daniël

Reply by email

Jonas Maebe
to Daniël Mantione
Daniël Mantione wrote 5 lines
Op Mon, 10 Sep 2012, schreef Jonas Maebe: > If you want to do that, you need to add a layer in between that converts the sets into integer bitmasks in a reliable, portable and future-proof way. Yes! Let's also convert integers to enums with a case statement rather than typecast, just in case the compiler may not count enums from zero in the future ;)

You can explicitly define the ordinal values of enumerations if you depend on that sort of stuff (which afaik the Qt units in fact do).

Jonas

Reply by email

Daniël Mantione
to Jonas Maebe

Op Mon, 10 Sep 2012, schreef Jonas Maebe:

Show quoted text 13 lines
On 10 Sep 2012, at 23:12, Daniël Mantione wrote: > Op Mon, 10 Sep 2012, schreef Jonas Maebe: > >> If you want to do that, you need to add a layer in between that converts the sets into integer bitmasks in a reliable, portable and future-proof way. > > Yes! Let's also convert integers to enums with a case statement rather > than typecast, just in case the compiler may not count enums from zero > in the future ;) You can explicitly define the ordinal values of enumerations if you depend on that sort of stuff (which afaik the Qt units in fact do).

That's a rewriting of history, as we invented that feature. Obviously people were writing interfaces to external libraries before that. Were those programmers wrong? Not at all, they could succesfully rely on guaranteed binary representations in Borland manuals.

Daniël

Reply by email

Jonas Maebe
to Daniël Mantione
Daniël Mantione wrote 5 lines
Op Mon, 10 Sep 2012, schreef Jonas Maebe: > You can explicitly define the ordinal values of enumerations if you depend on that sort of stuff (which afaik the Qt units in fact do). That's a rewriting of history, as we invented that feature.

With as primary reason: interfacing with external C libraries.

Obviously people were writing interfaces to external libraries before that. Were those programmers wrong? Not at all, they could succesfully rely on guaranteed binary representations in Borland manuals.

If the Borland defined that enumerations always start at 0, we will guarantee that too.

Jonas

Reply by email

Daniël Mantione
to Alexander Klenin

Op Tue, 11 Sep 2012, schreef Alexander Klenin:

Show quoted text 6 lines
On Tue, Sep 11, 2012 at 8:03 AM, Jonas Maebe wrote: > > If you want to do that, you need to add a layer in between that converts the sets into integer bitmasks in a reliable, portable and future-proof way. How about packed sets? Do they have well-defined memory layout? If not, then maybe they should?

Sets, are a bit more complicated: Their binary layout is defined in Borland documentation, but this one of the few issues were FPC didn't follow Borland. FPC has smallsets, up to 32 items and longsets, up to 256 items. This is how it is documented in FPC documentation. Packed is ignored on sets and I don't see a need for a packed set with a different binary representation, but *should* sets every become unreliable in binary representation, I would agree with you that there is a need for a packed set that is reliable.

Daniël

Reply by email

Jonas Maebe
to Alexander Klenin: How about packed sets? Do they have well-defined memory layout? If not, then maybe they…
Alexander Klenin wrote
How about packed sets? Do they have well-defined memory layout? If not, then maybe they should?

Set packing only influences the number of bytes occupied by sets, not their internal layout. And I don't think that should change, because they are orthogonal issues. You'd need a new directive that would enable unambiguously specifying the layout of sets. That would require a lot of code generator changes though.

And as an aside, using sets to represent bitmasks isn't even possible today if you want portable code, because the current layout on big endian systems does not correspond to or'ing (1 shl ord(enumval)). You could of course start changing the ordinal values of the enums on big endian systems to compensate, but then you get in trouble if they are sometimes also used in a non-bitmask context.

Jonas

Reply by email

Marco van de Voort
to Daniël Mantione: Op Tue, 11 Sep 2012, schreef Alexander Klenin: Sets, are a bit more complicated: Their…

In our previous episode, Dani?l Mantione said:

Sets, are a bit more complicated: Their binary layout is defined in Borland documentation, but this one of the few issues were FPC didn't follow Borland. FPC has smallsets, up to 32 items and longsets, up to 256 items.

That's outdated, running

{$packset 4}
type TBit64=0..63;
     TBitSet64 = set of TBit64;
begin
  writeln(sizeof(tbitset64));
end.

yields "8".

Last week I had to add this packset in addition to $Mode delphi to compile delphi code.

A difference with Delphi is that delphi iirc also allows multiple of 1s, and fpc only allows 1,2,4.. (multiples of 4 bytes)..32.

IIRC that had to do with endianess of sets, keeping them (d)word addressable. The 4 byte magnitude doesn't scale to 8 byte on 64-bit though.

Reply by email