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,f71c159449d6e114 X-Google-Attributes: gid103376,public From: "Chris Sparks (Mr. Ada)" Subject: Re: Ada 83 - avoiding unchecked conversions. Date: 1996/12/11 Message-ID: <32AED68A.48BE@aisf.com>#1/1 X-Deja-AN: 203528232 sender: Ada programming language references: comments: Gated by NETNEWS@AUVM.AMERICAN.EDU content-type: text/plain; charset=us-ascii organization: McDonnell Douglas mime-version: 1.0 newsgroups: comp.lang.ada x-mailer: Mozilla 3.0 (X11; I; HP-UX B.10.10 9000/712) Date: 1996-12-11T00:00:00+00:00 List-Id: Ensco Vendor wrote: > > we have two 16 bit integers which we need to assemble into a single 32 > bit integer (one is high order, the other low order). We wish to > avoid unchecked conversion if we can. Is there a standard accepted > way of doing this? Matt Heaney wrote: > > Unchecked conversion is the accepted way of doing this: It is an accepted way however not the only way. > function To_Integer_32 (Low, High : Integer_16) > return Integer_32 is > > type Integer_32_Record is > record > High_Order : Integer_16; > Low_Order : Integer_16; > end record; > > for Integer_32_Record use > record > High_Order at 0 range 16 .. 32; You mean 31. > Low_Order at 0 range 0 .. 15; You have to be careful here due to portability and bit ordering. > end record; > > for Integer_32_Record'Size use 32; > > function To_Integer_32 is > new Unchecked_Conversion ( > Integer_32_Record, > Integer_32); > > The_Record : constant Integer_32_Record := ( > High_Order => High, > Low_Order => Low); > begin > return To_Integer_32 (The_Record); > end; Here's Mine: with Interfaces; use Interfaces; with System; function To_Integer_32 (Low : in Integer_16; High : in Integer_16) return Integer_32 is type Integer_32_Record is record High_Order : Integer_16; Low_Order : Integer_16; end record; for Integer_32_Record use record High_Order at 0 range 16 .. 31; Low_Order at 0 range 0 .. 15; end record; for Integer_32_Record'Size use 32; The_Record : constant Integer_32_Record := (High_Order => High, Low_Order => Low); The_Record_Address : constant System.Address := The_Record'Address; Result : Integer_32; for Result'Address use The_Record_Address; -- New way --for Result use at The_Record_Address; -- Old way begin return Result; end To_Integer_32; with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; with To_Integer_32; procedure T is A : Integer_32 := -1; begin Put_Line ("A" & Integer_32'Image (A)); A := To_Integer_32 (Low => 10, High => 0); Put_Line ("A" & Integer_32'Image (A)); A := To_Integer_32 (Low => 0, High => 10); Put_Line ("A" & Integer_32'Image (A)); end T; I compiled this with 3.07 under HPUX and got the following results: A-1 A 655360 A 10 The low/high ordering is incorrectly represented for the HP (Portability issue). > Because the source and target types have the same size, this should be > completely portable. Yes. > Some shops have the rule "Thou shalt not use Unchecked_Conversion." > But this is silly; use it when it makes sense. I concur. Using Address Clauses would not be the right choice when a component within a structure has an initializing value (pointers, explicit initializations). > The proper place to use Unchecked_Conversion is at the interface > boundary of the sytem. That seems to be the case for you, because you're > manipulating types whose size is known explicitly (16 and 32 bit integers). I don't know what this means. Chris Sparks