On Wed, Nov 20, 2002 at 11:37:16AM -0500, CBFalconer wrote:
Emil Jerabek wrote:
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:
[...]
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 away.
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.
Sorry, no, that is not the problem. The problem is to check the storage into twobyte, IN ISOLATION. To check that such storage is possible requires READING the a value. There is no guarantee that a has already been initialized, AFAIK. At run time, even if a can be read, there is no place to find the twobyte limits. The compiler tables have long been discarded. To use them would require storing them (or a subset) in the object code, and could take a great deal of space. Consider a record type with 100
Checking that an assignment to the twobyte variant is legal does require reading the value of a, and I can't imagine any useful run-time check which wouldn't need to read some value :-) Once again, range check on the _value_ which is assigned to rcd.twobyte is an independent problem, and it needs only to know the bounds for the twobyte variant, not the whole (possibly large) table of such bounds for other variants. But maybe J. Bryan's last two posts explain this more clearly.
variants. The table must consist of at least 100 each minima and maxima. This is done all over again for each potential variant record type. Code has to be generated to access and index that table for every store into a variant item. We would probably also need to maintain a value for a outside it's normal range to indicate it has not been set, which forbids access to any variant.
It gets worse. The variants may be arrays of different sizes of differently sized components. Now we have to check the index value against some table and then check against the component limits. We do this at run-time, without the benefit of compiler symbol tables. Or the variants may have variants.
Note again the fact that the 'a' need not have been initialized when the twobyte storage is done.
This would be Microsoftian code bloat. I am not saying it is impossible, just that it is neither trivial nor really practical.
Range (or any other run-time) checking is always a code bloat. Its purpose is to assist debugging, and then it doesn't matter much that the code is huge and slow.
Let's do the easy stuff first. Range checking of indices and subranges, thinking of characters and booleans as subranges of integers. That will uncover most of the errors.
BTW, I believe something similar has already arisen in the usage of variant 10206 strings, where there is a need to store a capacity for each variant. In this case gpc has chosen to allocate completely separate storage areas for each variant, just to get the effect of such a table. I have other ideas on this, which don't belong in this thread.
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.
I am not really familiar with the 10206 spec, much more familiar with 7185, so I'll take your word on the otherwise usage and the range ranges. That just makes the problem more intractable.
Yes. But I think this feature is rarely used in practice, it's probably included in the standard just to make the syntax of variant records parallel to case statements.
Emil
Permitting them in the variant CASE means they need to be available in the executable code CASE, but the converse does not necessarily apply. Which is not germane anyhow.
-- Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net) Available for consulting/temporary embedded and systems. http://cbfalconer.home.att.net USE worldnet address!