The Chief wrote:
The way it is done in the System unit is invalid as well :-)
type
Integer = Integer (16);
As above, this should mean an attempt to make a circular definition. (Of course, the System unit is full of nonstandard features anyway, so this is not a real problem.)
Since it is already working, is there really a need to change it?
As Emil pointed out, it's not really working (only due to another bug of GPC).
Yes, you can - but I can't see the point. Anyone who wants to be standards-compliant will not use either the existing or the proposed new syntax.
It's not really a question of standard-compliance, rather a plain bug. E.g., even BP doesn't allow this:
var Integer: Integer;
or this (which is somewhat similar to `Integer = Integer (16)'):
type Integer = record a: Integer end;
For other people, the existing syntax does the job. There is nothing ambiguous in "Type foo = integer (n)", because if it is used in a type declaration (and that is the only place that it can be used), then it is clearly not a BP-style type-cast.
There is a problem with the way the System unit redeclares `Integer'.
Besides, consider:
type foo = Integer (16) .. 18;
Here it can only be a type-cast. Though not really ambiguous, it's hard to parse because you need much lookahead to tell the two cases apart.
That's part of a bigger problem with expressions as lower subrange-bounds which is still unsolved (in fact, it's the biggest parsing problem in GPC currently). `Integer (n)' is not alone responsible for it, but it adds to it and will not make a solution easier.
This could be changeg, e.g., to:
TypeOfSize (Integer, n) TypeOfSize (Word, n) TypeOfSize (Cardinal, n) TypeOfSize (Boolean, n)
This is fine - as (IMHO) is the original one. Both are non-standard. The original has 2 advantages - it is already working and being used, and, it doesn't require a new identifier.
But an ambiguous (or at least context-dependent) meaning with four identifiers.
CBFalconer wrote:
However, in GPC that's not exactly the same as `Integer (16)'. A subrange would still be a type of the same size as `Integer' (usually 32 bits) which is generally preferable for performance reasons, while strict BP compatibility sometimes requires a 16 bit type because some BP code relies on record layout etc.
While there is nothing wrong with that practice, I was always under the impression that the system was allowed to reduce the storage requirements for a subrange to whatever was needed. Without range checking the result is extremely dangerous, of course.
Sure it's allowed to. But GPC choses not to do so for normal subranges. I think in most cases that's preferable since often subranges are not declared to reduce storage (at the cost of performance), but to declare proper array indices etc.
This is one reason I see no purpose in extensions that supply other integral forms. Internal operations then remain on integers, only storage is affected. I guess an exception would have to be made for integral forms that can handle things larger than the system optimum integer, but that doesn't apply to gpc since, AFAIK, it doesn't have any integral forms larger than 32 bits.
It has 64 bit integers (on 32 bit systems), but that's no problem here, since subranges that exceed the 32 bit integer range become subranges of a 64 bit integer type automatically.
Emil Jerabek wrote:
If System were a module rather than unit, export renaming would do the job, IMHO:
export System = (Borland_Integer => Integer, ...)
...
type Borland_Integer = Integer (16);
That might be an option. It should be no problem to turn System into a module (since both units and modules can be used like units or imported as modules, this doesn't break compatibility).
One disadvantage would be that one would have to list all exported identifiers in the `...' part. That quite redundant IMHO. Of course, that's generally so with modules, but I don't like this very much. GPC has the extension `export foo = all', but it doesn't allow for export renaming, so it wouldn't be usable here, or we add renaming to it -- something like
export foo = all (BP_Integer => Integer);
J. David Bryan wrote:
On 11 Dec 2002 at 3:27, Frank Heckenbach wrote:
AFAICS, there is no easy and clean way to achieve what's wanted here. The following would be just as wrong, of course:
type Int16 = Integer (16); Integer = Int16;
Is there a semantic difference between:
type Int16 = Integer (16);
and:
type Int16 = packed -32768..32767;
That is, can the packed subrange form replace the specified-size form in all cases?
Internally, they're handled differently, so I'd have to check carefully if both yield exactly the same types in the end (but if not, it can maybe be fixed).
If so, this might justify dropping `Integer/Cardinal/Word (n)' entirely.
However, `Boolean (n)' cannot be done this way. It may be used for interfaces to other languages. But I'm not sure how widespread it is. Maybe we should also drop it (along with `ShortBool' etc.), and use integer types instead (and explicit `<> 0' comparisons or so) ...
Frank