From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c9b7709f7cadc963 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: Beware: Rep spec on an enumeration type clause Date: 1997/12/19 Message-ID: #1/1 X-Deja-AN: 308604951 Content-Transfer-Encoding: 8bit References: <34911237.81B700D6@iei.pi.cnr.it> <34912418.13716044@news.geccs.gecm.com> <349e19ec.16536708@news.geccs.gecm.com> <349a4134.5569381@news.geccs.gecm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Organization: Estormza Software Newsgroups: comp.lang.ada Date: 1997-12-19T00:00:00+00:00 List-Id: 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 else 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 (818) 985-1271