comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Re: Beware: Rep spec on an enumeration type clause
Date: 1997/12/19
Date: 1997-12-19T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023680001912970834080001@news.ni.net> (raw)
In-Reply-To: 349a4134.5569381@news.geccs.gecm.com


In article <349a4134.5569381@news.geccs.gecm.com>, brian.orpin@gecm.dot.com
wrote:

>In 83 it is imperative to check explicitly for valid ranges for external
>data in the absence of the 'Valid attribute.  On previous compilers this
>has been achieved by doing a type cast and forcing it to check.  The
>Tartan compiler always optimises this method away for exactly the reasons
>you state (I presume) so the explicit range check (as recommended by the
>manual) is the best way to check for valid data.

Yes, in Ada 83 you have to check too, I'm just saying there are smarted
ways to do it, ways that are guaranteed to work no matter which compiler
you're using.  For example, suppose I have a 8 bit message_id that has a
specific range:

type Message_Id is range 0 .. 10;
for Message_Id'Size use 16;

and I want to check it for validity (in Ada 83).  Here's what NOT to do:

Id : Message_Id;

procedure Get_Message is
begin
   Read (fd, Id);

   if Id in Message_Id then
      <process id>

   else
      <handle error>

   end if;
end Get_Message;

This is not guaranteed to work, for the reasons I cited earlier.  A better
way to do this is declare a subtype that occupies every value in the base
range of the type, as in

type Message_Id_Base is range 0 .. 255;

subtype Message_Id is Message_Id_Base range 0 .. 10;

Id : Message_Id_Base;  -- note the type here

Now when I do a membership test, 

if Id in Message_Id then -- note type here

then this really does have the behavior you want, and the test can't get
optimized away.  

This is exactly the kind of test you must do for enumeration types. 
Suppose Message_Id is an enumeration type:

type Message_Id is (A, B, C);
for Message_Id (2, 5, 9);

Whatever you do, never ever read into an object of type Message_Id, if the
object can have a value not in the set {2, 5, 9}.  Just ditch the rep
clause and check the value yourself.  Sometimes I also add an extra value
for the subtype:

type Message_Id is (A, B, C, Invalid);

function Get_Message_Id (File : File_Descriptor) return Message_Id is

   Id : Message_Id_Base;
begin
   Read (File, Id);

   case Id is
      when 2 => return A;
      when 5 => return B;
      when 9 => return C;
      when others => return Invalid;
   end case;
end Get_Message_Id;


This is why I think rep clauses for enumeration types don't even need to be
in the language.  You're mixing types that are at fundamentally different
levels of abstraction.  I didn't miss the Valid attribute in Ada 83, and
I'm kind of ho-hum about its presence in Ada 95.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




      parent reply	other threads:[~1997-12-19  0:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-12-12  0:00 Beware: Rep spec on an enumeration type clause Franco Mazzanti
1997-12-12  0:00 ` Ken Garlington
     [not found] ` <34912418.13716044@news.geccs.gecm.com>
1997-12-12  0:00   ` Ken Garlington
1997-12-12  0:00   ` Matthew Heaney
     [not found]     ` <349e19ec.16536708@news.geccs.gecm.com>
1997-12-18  0:00       ` Matthew Heaney
     [not found]         ` <349a4134.5569381@news.geccs.gecm.com>
1997-12-19  0:00           ` Matthew Heaney [this message]
replies disabled

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