Probs with variant records
ejer5183 at artax.karlin.mff.cuni.cz
Wed Nov 20 14:10:49 CET 2002
On Tue, Nov 19, 2002 at 04:55:47PM -0500, CBFalconer wrote:
> "J. David Bryan" wrote:
> > On 19 Nov 2002 at 12:00, CBFalconer wrote:
> > > This particular error is **very** hard to detect at run-time
> > > in any efficient manner.
> > I'm not sure I understand this. Is it not a matter of checking,
> > before each component access, whether the variant selector (or
> > selectors) is in the range of the corresponding case-constant-list?
> > Isn't that a simple range check, e.g., equivalent to that
> > performed before an assignment?
> No. Let's consider
> r = RECORD
> CASE a : integer OF
> 0: ( onebyte : 0..127);
> 1: ( twobyte : -5..512);
(BTW, one of these ENDs is spurious, I think.)
> rcd : r;
> r.twobyte := something; (* something may be an integer *)
> The compiler tables hold something describing the location of r,
> and offsets from there to a, onebyte, and fourbyte. It also holds
> acceptable ranges for each value. It can generate code (for a
> stack machine) something like:
> LDCA r (* address of r *)
> LDC offsetof twobyte
> ADD (forming address of twobyte, or maybe onebyte *)
> LOD something (* whatever is to be stored *)
> CHK minval, maxval (* which may cause an exception *)
> STI 1 (* putting it away *)
> 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. Where are those
> tables stored? Nothing insists that a be a valid initialized
> value before storing something in onebyte. Remember, onebyte and
> twobyte have the same offsets. They can store different
> subranges. a may have been set in another procedure far, far
Don't understand this. The problem was to check that the component
accessed is valid, which is as simple as ``r.a = 1?'' in your
example. Anyway the range check which you seem to be talking about
is also easy: the code stores something into r.twobyte,
hence the value should be range-checked against the definition
of twobyte, i.e. minval = -5 and maxval = 512. These bounds are
known at compile time, and they have nothing to do with the current
value of r.a.
> In addition, the compiler knows that it is storing a twobyte
> value. If it got it from something of appropriate type it knows
> it need not do a check on this store, and can totally elide the
> CHK operation. No such efficiencies if we have to read and
> translate the a value first.
> Without that check the only differences for storing onebyte and
> twobyte are the (known at compile time) values of minval and
> maxval, and quite possibly the operand of STI, which specifies the
> size of the thing to be written.
> In other words full checking here is a monstrous can of worms.
> Checking that the variant selector is in range never enters into
> it (except when storing that value at some other time). The names
Yes, it does. Here, the ``range'' was 1 .. 1, but the ISO 10206
standard permits a general range (or list of ranges) in such a situation.
R = record
case A: Integer of
0 .. 24, 29: (OneByte: 0 .. 127);
25, 30 .. 42: (TwoByte: -5 .. 512);
otherwise (MoreByte: Real)
> in the different variants are known to be disjoint (standard
> specified) so that the name used specifies the variant desired.
> Also there is no default "otherwise" clause in this flavor of a
> CASE statement AFAIK.
> Chuck F (cbfalconer at yahoo.com) (cbfalconer at worldnet.att.net)
> Available for consulting/temporary embedded and systems.
> <http://cbfalconer.home.att.net> USE worldnet address!
More information about the Gpc