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.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bb6f4bd169077fb3 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-02-07 20:42:01 PST Path: archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-09!supernews.com!news.maxwell.syr.edu!newsfeed-east.nntpserver.com!nntpserver.com!border1.nntp.aus1.giganews.com!nntp.giganews.com!nntp3.aus1.giganews.com!nntp.clear.net.nz!news.clear.net.nz.POSTED!not-for-mail NNTP-Posting-Date: Fri, 07 Feb 2003 22:39:09 -0600 From: Craig Carey Newsgroups: comp.lang.ada Subject: Re: Representing data differently Date: Sun, 09 Feb 2003 17:39:21 +1300 Message-ID: References: <686be06c.0302070615.3943b629@posting.google.com> X-Newsreader: Forte Agent 1.92/32.572 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Organization: Customer of Mercury Telecommunications Ltd Cache-Post-Path: drone5.qsi.net.nz!unknown@tnt2-144.quicksilver.net.nz X-Cache: nntpcache 2.4.0b5 (see http://www.nntpcache.org/) X-Original-NNTP-Posting-Host: drone5-svc-skyt.qsi.net.nz X-Original-Trace: 8 Feb 2003 17:38:59 +1300, drone5-svc-skyt.qsi.net.nz NNTP-Posting-Host: 203.97.37.6 X-Trace: sv3-oV9XbACKphesk/F1koixi4jmQW6nf42zfctTE3D5g7ST7lhJVIa0hXrhHyFq7KEEERRXqrOMXRQ60ks!Kk9rZZPryaLyq35xUZ/AThxCaxwbdxgUoesbABhoCOaXjgOiwA/DYMRdGC+dK+Qs6zT3D9e1akUD!PcM0dVs= X-Complaints-To: Complaints to abuse@clear.net.nz X-DMCA-Complaints-To: Complaints to abuse@clear.net.nz X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.1 Xref: archiver1.google.com comp.lang.ada:33904 Date: 2003-02-09T17:39:21+13:00 List-Id: On Fri, 07 Feb 2003 18:07:34 GMT, tmoran@acm.org wrote: >>In C I can represent the same data multiple ways using structs and >>unions. How and can I do this in Ada? > > In Ada it's called Unchecked_Conversion. It's "unchecked" because >there's not much the compiler can do to help check that you coded >what you meant to code. Look it up in any Ada text. This message provides a more details and it has an example showing how to make two records be of the same size. Suppose that there is a generic package that has to be instantiated only once (otherwise, with GNAT, the executables get larger), but the instantiated generic package has receive two completely different types. The generic package has this header: generic type Data_Type is private; -- Constrained only ... The package passes these 3 checks: * The 'union' type is not a pointer to both records. In this option and unchecked conversion would be done on the pointers. It is simple to specify but leads to harder to write code and probably a larger executable. * The 'union' type is not a variant, and it is not a tagged type. Those two types are unconstrained. -------------------------------------------------------------------- with Ada.Unchecked_Conversion; package Bt is type Kind_Enum is (Kind_R1, Kind_R2, Kind_Zero); -- Help catch unitialized value bugs in Linux: for Kind_Enum use (Kind_R1 => 7, Kind_R2 => 8, Kind_Zero => 9); pragma Volatile (Kind_Enum); -- Inlined code uses field's value type Hoof_Rec is null record; type R1_Rec is record X1 : Integer; end record; type R2_Rec is record Y1 : String (1 .. 7); Y2 : Boolean; end record; for Hoof_Rec'Alignment use 4; for R1_Rec'Alignment use 4; for R2_Rec'Alignment use 4; Size : constant := 64; -- Adjust by hand for Hoof_Rec'Size use Size; for R1_Rec'Size use Size; for R2_Rec'Size use Size; type Variant is record Kind : Kind_Enum := Kind_Zero; K : Hoof_Rec; end record; function From_R1 (X : R1_Rec) return Variant; function To_R1 is new Ada.Unchecked_Conversion ( Source => Hoof_Rec, Target => R1_Rec); private function From_R1 is new Ada.Unchecked_Conversion ( Source => R1_Rec, Target => Hoof_Rec); end Bt; -------------------------------------------------------------------- with Text_IO; package body Bt is function From_R1 (X : R1_Rec) return Variant is begin return (Kind => Kind_R1, K => From_R1 (X)); end From_R1; begin declare Z0 : Hoof_Rec; Z1 : R1_Rec; Z2 : R2_Rec; function Nim (Omicron : Natural) return String renames Natural'Image; function From_R1_To_R2 is new Ada.Unchecked_Conversion ( Source => R1_Rec, Target => R2_Rec); begin -- Prints "64 64 64 TRUE": Text_IO.Put_Line (Nim (Z0'Size) & Nim (Z1'Size) & Nim (Z2'Size) & ' ' & Boolean'Image (From_R1_To_R2 (Z1).Y2)); -- In GNAT,T'Object_Size to get the size of the variables -- without defining variables. if Z0'Size /= Z1'Size or Z0'Size /= Z2'Size then raise Program_Error; end if; end; end Bt; -------------------------------------------------------------------- pragma Style_Checks ("3abcefhiklmnoprst"); with Bt; procedure Bt_Main is begin null; end Bt_Main; -------------------------------------------------------------------- The text "From_R1_To_R2 (Z1).Y2" shows a way to use Unchecked_Conversion that permits the compiler to not copy the entire record. That is permitted by AARM 13.9 (Unchecked Type Conversions), which says: 12 An implementation may return the result of an unchecked conversion by reference, if the Source type is not a by-copy type. [In this case, the result of the unchecked conversion represents simply a different (read-only) view of the operand of the conversion.] 12.a Ramification: In other words, the result object of a call on an instance of Unchecked_Conversion can occupy the same storage as the formal parameter S. For GNAT, adding a ".all" and having the conversion be applying to a pointer to a record easily could reduce the chance of copying. -- For completeness, the Unchecked_Conversion feature and its copying, can be avoided, by using this technique: for X'Address use Y'Address; pragma Import (Y); -- :Stops default initialising of pointers (not in GNAT 3.14) If X or Y is an "in out" mode record parameter then it could be copied in or out. Making it tagged guarantees that that doesn't happen. AARM 3.10 (Access Types) says: (9.g) A formal parameter of a tagged type is defined to be aliased so that a (tagged) parameter X may be passed to an access parameter P by using P => X'Access. Access parameters are most important for tagged types because of dispatching-on-access-parameters (see 3.9.2). By restricting this to formal parameters, we minimize problems associated with allowing components that are not declared aliased to be pointed-to from within the same record. http://www.adaic.org/standards/95aarm/html/AA-3-10.html -------------- A bug that ACT got rid of has been replaced with another bug in the same place. In 15 July 2001 I reported this error as a bug (in GNAT 3.13p, the native FreeBSD version of FreeBSD): | 5. function Nim (Omicron : Natural) return String renames Natural'Image; | | | >>> warning: "Omicron" is not referenced With version 3.15p, there is still a warning (a minor problem): | 17. function Nim (Omicron : Natural) return String | 18. renames Natural'Image; | | | >>> (style): subprogram body has no previous spec G. A. Craig Carey Speedy Ada Strings. (The licence of the package changed: this software now can't be mixed with software under a licence having the acronym "GMPL", with 2 exceptions: (1) Ada Core Tech software is OK, it's exempted; (2) the "GMPL" text per file, of the 3rd party, is cryptographically signed by Ada Core, etc. R. R. Software seems to have its own GMPL -- I didn't see the acronym expanded, and while undefined it is different enough under law): http://www.ijs.co.nz/code/ada95_strings_pkg.zip http://www.ijs.co.nz/ada_95.htm