comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Rep Specing Variant Records
Date: Wed, 16 Sep 2009 08:03:37 -0700 (PDT)
Date: 2009-09-16T08:03:37-07:00	[thread overview]
Message-ID: <e70b8d9a-3868-4d09-b745-794674ea610a@m3g2000pri.googlegroups.com> (raw)
In-Reply-To: 2009091520225816807-rblove@airmailnet

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 say 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 entirely
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 for
Blah since it will never exist in a Normal_Stuff anyway.  But when the
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 that
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




  parent reply	other threads:[~2009-09-16 15:03 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 [this message]
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
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