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.
To implement a check for this requirement, the compiler might modify the above range-checking pseudo-code to:
if rcd.a = 1 then if something >= -5 and something <= 512 then rcd.twobyte := something else range_error else variant_error
Remember, onebyte and twobyte have the same offsets. They can store different subranges.
That is true but not relevant, because access always designates "onebyte" or "twobyte" and so the range is known to the compiler at the point of access from the type (and therefore appropriate range-checking code may be generated).
In other words full checking here is a monstrous can of worms.
It appears to me to be quite straightforward, unless I am missing your point entirely. Checking for correct variant accesses would appear to be a matter of adding a second range check (for the variant selector) to the range check presumed already present for assignment.
Note that Ada, e.g., requires that variant accesses be checked, i.e., it's not allowed for such checks to be omitted as in the Pascal standard. Using the GNU Ada compiler (GNAT) on an Ada program equivalent to your example, the compiler proceeds as I have outlined above, e.g., it generates run-time code to compare the value of the variant selector ("discriminant" in Ada- ese) to the case-constant-list ("discrete_choice_list") values before proceeding with the assignment. If the comparison fails, a "constraint error" is raised.
-- Dave