Another standard question. Is the following valid:
program Foo;
type t = record case Integer of 1: () end;
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.
Frank
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
Emil Jerabek wrote:
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 ...
You're right, in EP the type is wrong. OTOH, BP allows such a type. Then again, BP doesn't allow variant tags in `New' at all. So the issue arises only in GPC, when we combine EP and BP.
So, I think GPC should behave as follows (WRT my original example):
- In EP mode reject the type definition,
- in BP mode reject the `New' parameter,
- in GPC mode reject the value of the `New' parameter.
Nice.
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,
Sure, but the discriminated schema "is" the record, so the variant is at top-level then. But I don't mind to forbid it.
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): [...]
Now also in GPC. :-)
Frank