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,d3b2e17058959a22 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1995-03-21 18:28:02 PST Newsgroups: comp.lang.ada Path: nntp.gmd.de!news.rwth-aachen.de!news.rhrz.uni-bonn.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!xlink.net!howland.reston.ans.net!spool.mu.edu!uwm.edu!lll-winken.llnl.gov!noc.near.net!inmet!henning!stt From: stt@henning.camb.inmet.com (Tucker Taft) Subject: Re: C++ to Ada95, help please Message-ID: Sender: news@inmet.camb.inmet.com Organization: Intermetrics, Inc. X-Newsreader: TIN [version 1.1 PL8] References: <3kjd2m$d3t@jerry.rb.icl.co.uk> Date: Wed, 22 Mar 1995 01:22:05 GMT Date: 1995-03-22T01:22:05+00:00 List-Id: Simon Johnston (skj@rb.icl.co.uk) wrote: : Hi, thanks everyone for helping with my last query. I have a new C nasty for : you. I am converting some C headers into packages for use with GNAT and : have come accross the old chestnut: : typedef struct _STRUCT_NAME {.....type struct_STRUCT_NAME is : ....................................record : int item1;..........................item1 : int; : union { : : int u_item1; : : long u_item2; : : } u_name; : : int item2;..........................item2 : int; : ....................................end record; : } STRUCT_NAME;....................type STRUCT_NAME is new struct_STRUCT_NAME; : this I know is a contrived example but it does show the problem, how do I : describe the C struct on the left as an Ada record on the right. (The code : I have put on the right is lifted from the windows.ads package spec provided : in the GNAT examples directory for Windows NT. I believe GNAT supports a pragma "Unchecked_Union" (approximately) which is applied to a discriminated record to make it look like a C union. The basic model is that a C union is essentially an undiscriminated variant record. The pragma requests the compiler to omit the discriminant in memory, though it still exists "conceptually." To use this pragma, you would first declare your inner union as follows: type U_Name_Enum is (U_int, U_long); type U_Name_Union(Kind : U_Name_Enum := U_int) is record case Kind is when U_int => U_item1 : Interfaces.C.int; when U_long => U_Item2 : Interfaces.C.long; end case; end record; pragma Unchecked_Union(U_Name_Union); You can then use the "union" as a component of your record: type struct_STRUCT_NAME is record item1 : Interfaces.C.int; u_name : U_Name_Union; item2 : Interfaces.C.int; end record; You create values of the union type using a normal record aggregate, such as: X : U_Name_Union := (Kind => U_int, U_item1 => 33); The discriminant is required in the aggregate, even though no discriminant is actually stored in memory. I believe that the pragma Unchecked_Union causes an implicit "pragma Suppress(Discriminant_Check, On => );" so that no discriminant checks are performed when selecting a component of a union (caveat programmor). It is illegal to directly select the discriminant itself in the presence of this pragma. Note that for initial Ada-only unit testing you might want to comment out the pragma, so that discriminant checks are performed. Once you actually start interfacing with C, you will have to uncomment the pragma again to get rid of the space for the discriminant. It is hoped that this pragma will become a defacto standard for Ada 95 compilers that support interfacing to C. : |Simon K. Johnston - Development Engineer (C/C++) |ICL Retail Systems | : |------------------------------------------------------|3/4 Willoughby Road| : |Unix Mail : S.K.Johnston@bra0801.wins.icl.co.uk |Bracknell, Berks | : |Telephone : +44 (0)344 476320 Fax: +44 (0)344 476302|United Kingdom | : |Internal : 7261 6320 OP Mail: S.K.Johnston@BRA0801|RG12 8TJ | -Tucker Taft stt@inmet.com Intermetrics, Inc.