On Thu, Feb 27, 2003 at 12:58:39AM +0100, Frank Heckenbach wrote:
Another standard question. Is the following valid:
program Foo;
type t = record case Integer of 1: () end;
Isn't this an invalid type definition?
From section 6.4.3.4 (the last sentence is relevant):
Each value denoted by a case-range of the case-constant-list of a variant-list-element shall be designated as corresponding to the variant denoted by the variant-denoter of the variant-list-element. Each value, if any, of the variant-type of a variant-part that is not denoted by a case-range of the case-constant-list of a variant-list-element of that variant-part shall be designated as corresponding to the variant denoted by the variant-denoter of the variant-part-completer of the variant-part. Each value possessed by the variant-type of a variant-part shall correspond to one and only one variant of the variant-part.
So, IIUIC, you should use either
type Range = 1 .. 1; t = record case Range of 1: () end;
(which makes the `New' statement invalid), or
type t = record case Integer of 1: () otherwise () end;
(then the problem disappears).
var v: ^t;
begin New (v, 2) end.
Some of GPC's test programs (not written by me) do something like this, but I doubt whether that's ok. As usual, the language of the standard (6.7.5.3 in EP) is somewhat confusing, so I'm better asking to be sure ...
Another thing: The standard allows to set variant tags or schema discriminants in `New', but not both together. Is this an artificial restriction, or would there be some deeper problem with code like this:
program Foo;
type t (n: Integer) = record case Integer of 1: () end;
var v: ^t;
begin New (v, 42 { discriminant }, 1 { variant tag }) end.
I can't see a problem here (except for the selector type, as above). Maybe the standard prohibits such a usage for consistency -- in general, variant selectors in `New' are allowed only directly for records, not for structured types which contain a record at a deeper level, and this has a good reason in some cases: consider e.g.
program Foo2;
type t = array [1 .. 100] of record case Boolean of True: (); False: () end; var v: ^t;
begin New (v, ???) end.
If allowed, should it be `New (v, True)' (making all 100 variants the same), or `New (v, True, True, False, True, False, False, ...[100 times])'?
Moreover, mixed discriminants and variant tags in `New' can always be avoided by a simple modification of the schema (in the standard, not in GPC):
program Foo3;
type t (n, Tag: Integer) = record case Tag of 1: () otherwise () end;
var v: ^t;
begin New (v, 42 { discriminant }, 1 { also discriminant }) end.
Emil