comp.lang.ada
 help / color / mirror / Atom feed
From: ncohen@watson.ibm.com (Norman H. Cohen)
Subject: Re: Range Check Query
Date: 21 Nov 1994 16:00:16 GMT
Date: 1994-11-21T16:00:16+00:00	[thread overview]
Message-ID: <3aqg6g$o55@watnews1.watson.ibm.com> (raw)
In-Reply-To: 9411181527.AA08827@eurocontrol.de

In article <9411181527.AA08827@eurocontrol.de>, Bob Wells #402
<wel@EUROCONTROL.DE> writes: 

|> Why does the following not raise a Constraint_Error exception?
|> (It doesn't even raise a compile time warning)
|>
|>   type dn18906 is  -- layout is for the 18906 message  .
|>     record
|>       dnspare  : integer range 0 .. 1;
...
|>     end record;
|>
|>    for dn18906 use
|>      record at mod 1;
...
|>      end record;
|>
|>    for dn18906'size use 24;
|>
|>    type Dn_189_Data is array(1 .. N_Data) of Dn18906;
|>    pragma Pack(Dn_189_Data);
|>
|>    M_T : Dn_189_Data;
|>    for M_T use at P_Mesg_Conv(P_Ohead) + 12;
|>
|> P_Mesg_Conv is an Unchecked_Conversion of an access type to a
|> system address. The access type points to an incoming byte
|> stream.
...
|> OK, then in the body of this package we have: 
|>
|>
|>    if M_T(1).Dnspare = 2 then
|>
|> --     do something
|>
|>    end if;
|>
|> The incoming stream definitely has value of 2 occaisionaly in this
|> component yet it doesn't raise Constraint_Error?

As others have pointed out, the actual error arises during the unchecked
conversion.  In the words of RM 13.10.2(3), "Whenever unchecked
conversions are used, it is the programmer's repsonsibility to ensure
that these conversion maintain the properties guaranteed by the language
for objects of the target type.  Programs that violate these properties
by means of unchecked conversions are erroneous."

This leaves the question of why unchecked conversion doesn't raise
Constraint_Error.  The answer:  If it did, they'd have to call it checked
conversion.

The solution to your problem:  In Ada 9X, use the attribute M_T(1)'Valid;
in Ada 83, check the validity of your bits before uncheckedly converting
to dn18906.  One way to do this is to define a type in which each
possible combination of bits represents a valid value, e.g.: 

   type Raw_Unvalidated_dn18906 is  -- layout is for the 18906 message  .
     record
       dnspare  : integer range 0 .. 3; -- instead of 0 .. 1
...
     end record;

    for Raw_Unvalidated_dn18906 use
      record
         dnspare at 0 range 0 .. 1;
...
      end record;

Uncheckedly convert to (a pointer to) this type first, which is
guaranteed not to be erroneous because every bit pattern represents a
valid value of this type.  If the dnspare component is 2 or 3, reject the
data as invalid.  Otherwise, use it as valid data.  It's a matter of
taste whether, having performed this explicit test, you want to convert
to (a pointer to) dn18906 afterward, to document the fact that the data
has been validated and is known to obey the constraints of that type.

--
Norman H. Cohen    ncohen@watson.ibm.com



  parent reply	other threads:[~1994-11-21 16:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-11-18 15:27 Range Check Query Bob Wells #402
1994-11-18 12:11 ` Robert I. Eachus
1994-11-19 16:58   ` Robert Dewar
1994-11-21 10:57     ` Robert I. Eachus
1994-11-20 17:16 ` Do-While Jones
1994-11-21 16:00 ` Norman H. Cohen [this message]
1994-11-23 17:31 ` Kent Mitchell
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox