Adriaan van Os wrote:
Waldek Hebisch wrote:
I do not understand what is your point here. Do you argue "in abstract" or maybe you have some concrete proposal what to change in GPC?
Based on Frank's and Peter's comments, I propose the following:
- Predefine 2 pseudo-schema types to define signed and unsigned
integral types:
IntegerWithBits (n) CardinalWIthBits (n)
where n is a compile-time constant expression.
BTW, native speakers, with formulation is better, "integer with/of N bits"?
Examples:
Type Int16 = IntegerWithBits( 16); {defines an integer type in the range -32768 .. 32767} Word32 = CardinalWIthBits( 32); {defines a cardinal type in the range 0..$FFFFFFFF} RealInt = IntegerWithBits( BitSizeOf( Real)); {defines an integer type with the same size as a Real}
Note that BooleanWithBits is not needed, as a Boolean has only one bit of data (also see below).
- Deprecate the Size attribute (issue a warning that it will be
removed).
Example:
Type Int64 = Integer attribute( size = 64); {warning: use of the Size attribute is deprecated; this will be an error in a future compiler release}
- Optionally, implement a Bitsize attribute for all types except
arrays. The Bitsize attribute will add pad bits if needed and it will check that the type fits in the given number of bits.
Examples:
Type Int16 = Integer attribute( bitsize = 16); {error on most platforms: the referenced `Integer' type doesn't fit into 16 bits}
Yes, but both `Byte attribute (BitSize = 16)' and `0 .. 255 attribute (BitSize = 16)' would be allowed and result in a 16 bit type, despite the fact that the original types are (currently, on most platforms) 8 and 32/64 bits large.
Bool32 = Boolean attribute( bitsize = 32); {defines a 32-bit Boolean} Sex8 = ( female, male) attribute ( bitsize = 8); {defines an 8-bit enumerated type}
OK.
Style8 = set of (plain, boldface, italic, underline) attribute( bitsize = 8); {error: the `Style8 ' set type doesn't fit into 8 bits} PaddedCharsRecord = record c: array[ 0..2] of Char end attribute( bitsize = 32); {make sure the record is 32-bit aligned}
I'm doubtful it will work for such structured types. For records, we are bound to the backend features, and I don't think it allows bit-padding (except for bit-packed records, i.e. packed records in Pascal).
Also I think you mixed up padding and alignment -- padding to 32 bit does not necessary mean alignment (e.g., if padding were done by adding another hidden Char field, it would still be Char-aligned).
For sets, we're bound by our RTS implementation which is based on (currently) MedCard sized units. Any other padding would make no sense (unless/until we add special support for small sets, but that's a different issue).
Also for reals and pointers (or even file types), I don't see much sense in padding, and it would probably be hard to implement it. (One could wrap them in a record with padding, but then each access would internally have to access the implicit record field.)
So I think it really reduces to ordinal types. (And in fact, except within packed records/arrays, only sizes of default integer types, i.e. usually powers of 2 from 8 to BitSizeOf (LongestInt), make sense, as otherwise padding will round up to such a power of two.)
I think, source code incompatibilities will be bearable, because the compiler will issue warnings where current source code has to be changed. The only remaining issue is that n-bit-padded booleans can no longer be defined if (3) is not implemented.
which suggests to implement (3) at least for Booleans.
Actually, with (3) we could get by without the pseudo-schemata, as e.g.
CardinalWithBits (n)
would be the same (for n >= 2) as
0 .. (1 shl (n - 2) - 1) shl 2 + 3 attribute (BitSize = n)
(the expression looks a bit complicated to avoid overflow in the maximum-size case).
As such types should be declared rarely (and if there are several of them in one unit, the typical case, the above can be hidden in a macro), this might be bearable.
Frank