comp.lang.ada
 help / color / mirror / Atom feed
From: Robert Love <rblove@airmail.net>
Subject: Re: Rep Specing Variant Records
Date: Thu, 17 Sep 2009 21:28:15 -0500
Date: 2009-09-17T21:28:15-05:00	[thread overview]
Message-ID: <2009091721281516807-rblove@airmailnet> (raw)
In-Reply-To: 7ba04f56-6b57-437d-bf38-309d2dbb4b21@y20g2000vbk.googlegroups.com

On 2009-09-17 03:25:19 -0500, Martin <martin.dowie@btopenworld.com> said:

> On Sep 17, 3:39�am, Robert Love <rbl...@airmail.net> wrote:
>> First, thanks to all who answered my question.
>> 
>> My big concern about the presence of a discriminant in the derived type
>> is that I'm shipping the record out via ether net to a C client to
>> read. �The C program will not tolerate the extra discriminate.
>> 
>> I have two very similar layouts in the input and output data. �I had
>> hoped to use variant records to save me some typing and coding. �I now
>> believe I will have to have two complete records, one for input and one
>> for output that will have 80% common structure. �Oh, well, it's just
>> more typing.
>> 
>> On 2009-09-16 10:03:37 -0500, Adam Beneschan <a...@irvine.com> said:
>> 
>>> On Sep 15, 6:22�pm, R.B. Love <rbl...@airmail.net> wrote:
>>>> I want to understand how a variant record gets rep spec'd. �Let's sa
> y I
>>>> have a sample of my record:
>> 
>>>> type stuff(has_extra:boolean) is
>>>> record
>>>> � � foo: integer;
>>>> � � bar: integer;
>>>> � � case has_extra
>>>> � � � � when true =>
>>>> � � � � � � blah : float;
>>>> � � � � when false =>
>>>> � � � � � � null;
>>>> � � end case;
>>>> end record;
>> 
>>>> for stuff use
>>>> record
>>>> � � foo at 0 range 0..31;
>>>> � � bar at 4 range 0..31;
>>>> end;
>> 
>>>> type normal_stuff is new stuff(has_extra=>false);
>>>> type good_stuff is new stuff(has_extra=>true);
>> 
>>>> for good_stuff use
>>>> record
>>>> � � blah at 12 range 0..31;
>>>> end record;
>> 
>>>> for normal_stuff'size use 64; �-- 8 bytes
>>>> for good_stuff'size use 96; � �-- 12 bytes
>> 
>>>> First, does the discriminant take up any size in the record?
>> 
>>> In "stuff", it almost certainly takes space. �If you have a procedure
>>> with a parameter X of type "stuff", and that procedure looks at
>>> X.Has_Extra, the procedure has to get that data from somewhere, and it
>>> will almost certainly get it from some field in X. �The discriminant
>>> *could* be passed as a separate parameter, but that would be atypical.
>> 
>>> For your derived types, normal_stuff and good_stuff, whether the
>>> discriminant takes space depends on the implementation. �If you didn'
> t
>>> put any rep clauses on those types, they would probably have the exact
>>> same representation as "stuff" because then type conversions would be
>>> implemented just as straight copy operations. �But eliminating the
>>> space for the discriminant is also possible. �(By the way, you can't
>>> put a rep clause on the derived type under certain circumstances---see
>>> 13.1(10)).
>> 
>>>> When I
>>>> tried this with a tagged record, I was told that my placement at 0
>>>> bytes off set classed with the tag. �That's no good.
>> 
>>> Tagged records are a completely different animal, here. �First of all
> ,
>>> you cannot declare a type extension and rearrange any fields
>>> (including discriminants) that existed in the parent type; you
>>> couldn't get dispatching to work if you were allowed to rearrange
>>> those fields. �You can only use a rep clause to rearrange new fields
>>> in the type extension. �Second, you definitely can't move the tag to
> a
>>> different place than in the parent type. �That would just blow
>>> everything up.
>> 
>>> Finally, although it's theoretically possible to have tags in
>>> different places for two different (non-derived) tagged types, it
>>> makes implementing the language a lot more difficult. �This is even
>>> more true now that interface types have been introduced in Ada 2005.
>>> (If you declare a root type Root_Type with a tag in a nonstandard
>>> place, and then later "type Child is new Root_Type and Interface_Type
>>> with...", then how is an operation on Interface_Type'Class going to
>>> know where to find the tag if you give it a Child?) �So it is entirel
> y
>>> reasonable for a compiler to insist on the tag being in a set place
>>> for every tagged type.
>> 
>>> I don't know what you say this is "no good"---what are you trying to
>>> accomplish? �Whatever it is, you're probably going about it wrong.
>> 
>>>> Second, does the layout of normal_stuff look like I expect it would,
>>>> that is, the same as stuff?
>> 
>>> If the 'Size clause on Normal_Stuff is legal, then probably not.
>>> Stuff has to have room for two integers, a float, and a Boolean; if
>>> Integer'Size is at least 16 and Float'Size is at least 32, then
>>> Stuff'Size will be larger than 64, which means that the only way
>>> Normal_Stuff'Size could be legally 64 would be for the compiler to not
>>> allocate space for some fields. �That may mean not allocating size fo
> r
>>> Blah since it will never exist in a Normal_Stuff anyway. �But when th
> e
>>> compiler realizes it will need to rearrange fields, there's no telling
>>> what it will do.
>> 
>>> Even if Integer'Size is 16, it's entirely possible that the compiler
>>> will allocate 32 bits for Foo and Bar to help with the machine's
>>> alignment requirements. �If that's the case, and if it accepts "for
>>> Normal_Stuff'Size use 64" as legal, it will need to rearrange things.
>> 
>>> So the answer to your question is "maybe, maybe not".
>> 
>>>> Does the good_stuff record have a complete rep spec?
>> 
>>> I don't know what you mean by this. �The language doesn't require tha
> t
>>> a rep spec specify every field. �If you don't, the compiler will put
>>> the additional fields anywhere it feels like (and not necessarily in
>>> the same place where they exist in a Stuff). �So this is a legal rep
>>> spec.
>> 
>>> � � � � � � � � � � � � � � � � � �
>  � �-- Adam
>> 
>> 
> 
> type A_Common_Part is
>    record
>       I : Integer;
>       F : Float;
>    end record;
> 
> type An_Input is
>    record
>       CP : A_Common_Part;
>    end record;
> 
> type An_Output is
>    record
>       CP : A_Common_Part;
>       C  : Character;
>    end record;
> 
> Wouldn't that do?
> 
> Cheers
> -- Martin


Yes, it would.  I'm already compositing smaller records into the big 
input and output records.  A record for the electrical data, one for 
the navigation data etc.

This was really an chance for me to experiment with variant records, to 
look into a corner of the language I don't use.  I learned a lot





  reply	other threads:[~2009-09-18  2:28 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-16  1:22 Rep Specing Variant Records R.B. Love
2009-09-16  8:19 ` Petter
2009-09-16 10:10 ` Martin
2009-09-16 15:03 ` Adam Beneschan
2009-09-17  2:39   ` Robert Love
2009-09-17  6:57     ` Niklas Holsti
2009-09-17  8:25     ` Martin
2009-09-18  2:28       ` Robert Love [this message]
2009-10-10  2:49   ` Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox