TEAM-ADA Archives

Team Ada: Ada Programming Language Advocacy


Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Condense Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
"Team Ada: Ada Advocacy Issues (83 & 95)" <[log in to unmask]>
Steven Deller <[log in to unmask]>
Thu, 22 Oct 1998 12:03:37 +0200
Mats Weber <[log in to unmask]>
text/plain; charset=us-ascii
ELCA Matrix SA
text/plain (134 lines)
(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).

      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
            (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;

         -- berk
            if Message_Type'Base'Object_Size = 0 then
               Max_Length := 0;
               Max_Length := (Message_Type'Base'Object_Size - 1) /
System.Storage_Unit + 1;
            end if;
            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;
            (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.