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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no 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 15:27:35 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!cs.utexas.edu!news.sprintlink.net!pipex!peernews.demon.co.uk!news2.demon.co.uk!banana.demon.co.uk!kevq From: kevq@banana.demon.co.uk (Kevin F. Quinn) Subject: Re: C++ to Ada95, help please X-Nntp-Posting-Host: banana.demon.co.uk Message-ID: <19950321.232735.72@banana.demon.co.uk> Sender: news@demon.co.uk (USENET Administrator) Reply-To: kevq@banana.demon.co.uk Organization: The Banana Arc X-Newsreader: Archimedes TTFN Version 0.36 References: <3kjd2m$d3t@jerry.rb.icl.co.uk> Date: Tue, 21 Mar 1995 23:27:35 GMT Date: 1995-03-21T23:27:35+00:00 List-Id: In article <3kjd2m$d3t@jerry.rb.icl.co.uk>, skj@rb.icl.co.uk (Simon Johnston) 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. > > Thanks. Yeuch! If "int" and "long" are not the same size, any amount of tricksy mucking about could happen. I would be tempted to write: type u_name_union_type is record u_item1 : Unsigned_Integer; <- or whatever. u_item2 : Unsigned_LongInteger; <- end record; type struct_STRUCT_NAME is record item1 : Integer; u_name : u_name_union_type; item2 : Integer; end record; in the first instance. The naming structure would then remain, although the actual data layout would be different. If the layout is important, then how about: type struct_STRUCT_NAME is record item1 : Integer; u_name : LongInteger; <-- type is the size of the union. item2 : Integer; end record; function u_item1(u_uname : in LongInteger) return Integer; function u_item2(u_uname : in LongInteger) return LongInteger; where function u_item1 returns the lower half of the u_name parameter (several ways to do this - best way will depend on the compiler). Unfortunately, this mucks up the naming structure; you need to use item1_value := u_item1(struct.u_name); instead of item1_value := struct.u_name.u_item1; (which works with the top version). Of course, unions are usually used in 'C' for variant records, which you can do in Ada. 'twill depend on how well the compiler allows you to specify the actual layout of the variant record that decides whether this would work well enough. It's unlikely, though, given the layout above. You could declare a separate type for each union element, then declare several data items, and alias them [fx: throws up :) ] For example: type u_name_item1_type is record u_item1 : Integer; padding : Integer; <-- Assuming LongInteger'size=2xInteger'size end record; Anyway, in general some padding will be required. type u_name_item2_type is record u_item2 : LongInteger; end record; type struct_STRUCT_NAME is record item1 : Integer; u_name : u_name_item1_type; item2 : Integer; end record; type struct_STRUCT_NAME_item2 is record item1 : Integer; u_name : u_name_item1_type; item2 : Integer; end record; DataItem : struct_STRUCT_NAME; DataItem2 : struct_STRUCT_NAME_item2; for DataItem2 use at DataItem'Address; and use DataItem2 whenever you need to access .u_name.u_item2. Hmm. Interesting problem. There's probably a nice simple solution; I just can't see one :) -- Kevin F. Quinn * "That's not what you said when you sent him your kevq@banana.demon.co.uk * Navel." "Novel, Baldrick, not navel." kevq@cix.compulink.co.uk * "Well it sounds like a case of soggy grapefruits Compu$erve: 100025,1525 * to me..." BlackAdder III ... Death is proven to be 99.9% fatal to all laboratory rats.