Mats,
I find GNAT's object_size interesting and may push for this to be added to
Rational's Apex.  However, I find the definition lacking in precision,
making it unclear what to ask for.

My interpretation of the GNAT documentation is that the intention for
typename'object_size is to be equivalent to declaring an object of typename
and taking 'size of that object.

My problem is that GNAT does not appear to follow that definition.

Specifically, take the example of
  type x record is
    i : integer ;
    b : short_short_integer ;
  end record ;

According to GNAT documentation, x'object_size should be 64.  But that would
seem to depend on what object follows the object declaration.  For example,
suppose we have the declarations:

   objectx : x ;
   objectssi : short_short_integer ;

Then you would find, at least on Apex, that objectssi started 5 bytes after
objectx, since objectx only actually occupies 5 bytes and objectssi only
needs byte alignment.  It seems to me that if an object may only occupy 5
bytes, then object_size should be 40, not 64. With the GNAT definition, one
could construct a case where the sum of object_size for components of the
record was greater than object_size for the record -- that seems
counter-intuitive.

Now we could have this attribute yield different values on different
compilers, but that would seem to be something we are trying to avoid.
  (Actually, two different values is ok if the *meaning* of the attribute is
identical and the meaning is consistent with the usage in the application
program.)

For your example, T'alignment has no importance on Apex (and as I said, I
still fail to see why it is important on GNAT).  You need only take
T'base'size and round it up to the next byte to find the size of an object
of that type.  Since your code already uses 'base and already does rounding
up, you need only change "object_size" to "size" to have it work on Apex.
 Hence my continuing confusion about why object_size is needed at all.

Regards,
Steve

On Thursday, October 22, 1998 3:04 AM, Mats Weber
[SMTP:[log in to unmask]] wrote:
> (I am copying this to the list, as there might be interest).
>
> Steven Deller wrote:
> >
> > Mats,
> > Could you elaborate on where you think 'object_size is required?  And
> > could
> > you also elaborate on what you think the spec is for 'object_size (I'd
> > like
> > to consider asking for this to be added to Apex, if there is truly a
> > need).
>
> Your phrasing seems to imply that 'Object_Size is not really necessary,
> but the GNAT people would not have invented it if this were true :-)
>
> Anyway, here is a piece of code where I need it. This generic is used to
> send any type over a socket (on the same machine, so I don't need to
> care about endianity issues, and I need it to be as fast as possible).
>
> It must work with indefinite types (e.g. String, and records with
> discriminants that have defaults).
>
> I suppose I could replace T'Object_Size with some formula involving
> T'Size and T'Alignment, but T'Object_Size is really easier.
>
> I know, I am supposed to use the streams stuff for this kind of thing,
> but this is old code that works and I am not going to rewrite it.
> Besides, I cannot afford the overhead that I assume this would add (I
> haven't done any tests, though).
>
>    generic
>       type Message_Type (<>) is private;
>    package Communications is
>    ----------------------
>
>       -- Higher level communications.
>       -- If Message_Type has discriminants, then they
>       -- must have a default initial value.
>
>       procedure Send (To      : in Subprocess_Link;
>                       Message : in Message_Type);
>          -- Sends Message to To.
>          -- Raises Link_Not_Open if To is not open.
>
>       procedure Receive (From    : in Subprocess_Link;
>                          Message : out Message_Type);
>          -- Receives the next message from From.
>          -- If Message_Type has discriminants, then
>          -- the actual parameter for Message MUST NOT
>          -- BE CONSTRAINED.
>          -- Raises Link_Not_Open if From is not open.
>
>    end Communications;
>
>
>    package body Communications is
>    ---------------------------
>
>       procedure Send (To      : in Subprocess_Link;
>                       Message : in Message_Type) is
>       begin
>          Low_Level_Communications.Send
>             (To     => To,
>              Buffer => Message'Address,
>              Length => Message'Size / System.Storage_Unit);
>       end Send;
>
>
>       procedure Receive (From    : in Subprocess_Link;
>                          Message : out Message_Type) is
>
>          Length_Received : Natural;
>          Max_Length      : Natural;
>
>       begin
>          -- berk
>          begin
>             if Message_Type'Base'Object_Size = 0 then
>                Max_Length := 0;
>             else
>                Max_Length := (Message_Type'Base'Object_Size - 1) /
> System.Storage_Unit + 1;
>             end if;
>          exception
>             when Constraint_Error =>
>                -- due to evaluation of Message_Type'Base'Object_Size,
>                -- which can be an unconstrained type such as String
>                Max_Length := (Message'Size - 1) / System.Storage_Unit + 1;
>          end;
>          Low_Level_Communications.Receive
>             (From            => From,
>              Buffer          => Message'Address,
>              Max_Length      => Max_Length,
>              Length_Received => Length_Received);
>       end Receive;
>
>    end Communications;
>
> For completeness, here is the GNAT documentation on 'Object_Size:
>
> > Object_Size
> >       The size of an object is not necessarily the same as the size
> >       of the type of an object. This is because by default object
> >       sizes are increased to be a multiple of the alignment of the
> >       object. For example, Natural'Size is 31, but by default
> >       objects of type Natural will have a size of 32 bits.
> >       Similarly, a record containing an integer and a character:
> >
> >        type Rec is record
> >           I : Integer;
> >           C : Character;
> >        end record;
> >
> >       will have a size of 40 (that is Rec'Size will be 40. The
> >       alignment will be 4, because of the integer field, and so the
> >       default size of record objects for this type will be 64 (8
> >       bytes). The type'Object_Size attribute has been added to GNAT
> >       to allow the default object size of a type to be easily
> >       determined. For example, Natural'Object_Size is 32, and
> >       Rec'Object_Size (for the record type in the above example)
> >       will be 64. Note also that, unlike the situation with the
> >       Size attribute as defined in the Ada RM, the Object_Size
> >       attribute can be specified individually for different
> >       subtypes. For example:
> >
> >        type R is new Integer;
> >        subtype R1 is R range 1 .. 10;
> >        subtype R2 is R range 1 .. 10;
> >        for R2'Object_Size use 8;
> >
> >       In this example, R'Object_Size and R1'Object_Size are both 32
> >       since the default object size for a subtype is the same as
> >       the object size for the the parent subtype. This means that
> >       objects of type R or R1 will by default be 32 bits (four
> >       bytes). But objects of type R2 will be only 8 bits (one
> >       byte), since R2'Object_Size has been set to 8.