"J. David Bryan" wrote:
On 19 Nov 2002 at 16:55, CBFalconer wrote:
VAR rcd : r; .... r.twobyte := something; (* something may be an integer *)
I assume you mean "rcd.twobyte := something" here.
Now, where is the compiler going to get the values of minval and maxval? To do so it would have to read a, and translate that somehow into minval and maxval at run time.
Not at all. The assignment to "twobyte" means that the range is known at compile time from twobyte's type, so the (run-time) check can be generated with constants. That's no different from any other run-time range check, e.g. in pseudo-code:
rcd.twobyte := something
might be generated by the compiler as:
if something >= -5 and something <= 512 then rcd.twobyte := something else range_error
Nothing insists that a be a valid initialized value before storing something in onebyte.
The standard does. From my original post from ISO 10206, section 6.5.3.3:
"It shall be an error unless a variant of a record-variable is active for the entirety of each reference and access to each component of the variant."
This insists that not only must "a" be a valid value, the value must correspond with the case-constant-list associated with the accessed variant, because a particular variant is only "active" if "a" is set appropriately.
You are right - that provision makes a world of difference. There is still the problem of untangling nested variants. And the multiple ranges per variant, as pointed out by Emil, complicates that variant selector check, unless I am again confused. This means the variant check has to be something like (variation on your code, snipped):
selectorok := false; v := firstrange; (* How to handle otherwise?? *) while selectorok and (v <= lastrange) do if rcd.a >= v.minrangept or rcd.a <= v.maxrangept then selectorok := true else v :=- succ(v); if not selectorok then varianterror else if (value <= id.minvalue) or (value > id.maxvalue) then rangerror; else store(value, runtimeaddress^);
where everything except v, value and selectorok are compile time constants. It is still a lot of code to emit to store a single char in a variant field! :-) This allows the restrictions on the source of value to eliminate the minvalue/maxvalue checks. Anything of this nature should be suppressable without destroying generalized range checks.
This logic can probably be simplified with unrestricted set size. But consider:
r = RECORD CASE i : integer OF 0..1000, 10000: (c : char); -9999, 3000..4000: (j : integer); END; (* r *)
Note the negative value!!
I remain unconvinced that ranges in variant selectors are a GOOD THING.