comp.lang.ada
 help / color / mirror / Atom feed
From: joakimds@kth.se
Subject: Re: Calling a record type's methods (functions or procedure) when record is in an array
Date: Fri, 24 Jan 2020 01:47:26 -0800 (PST)
Date: 2020-01-24T01:47:26-08:00	[thread overview]
Message-ID: <e8f81d93-a54f-4470-8d45-fecc00f29d95@googlegroups.com> (raw)
In-Reply-To: <lyo8uunmk9.fsf@pushface.org>

Den torsdag 23 januari 2020 kl. 17:51:22 UTC+1 skrev Simon Wright:
> joakimds@kth.se writes:
> 
> > Other issues?
> 
> Alignment?
> 
> =========
> 
> Looks to me like something it would be better not to do, even if you can.

Hi Simon,

Not entirely sure how Alignment can interfere but I can realize that using controlled types in the Taft type defined in the body may yield unexpected results. Right now I am leaning towards better not to do even if one can. However, here is another implementation that may be less error prone:

package Cars is

   type Any_Holder is abstract tagged limited null record;
   
   function Make_Holder return Any_Holder'Class;
   
   type Any_Car (<>) is limited private;
   --  This type is defined with unknown discriminant in order to make
   --  sure instances are properly initialized by allocator function.
   
   function Allocate_Car (Holder : in out Any_Holder'Class) return Any_Car;
   --  The allocator function.

   type Car_Passenger_Count is range 0 .. 5;
   
   function Passenger_Count (Car : Any_Car) return Car_Passenger_Count;

   procedure Set_Passenger_Count
     (Car   : in out Any_Car;
      Value : Car_Passenger_Count);

private

   type Taft_Car;

   type Any_Car
     (Reference : not null access Taft_Car)
   is limited null record;

end Cars;

package body Cars is

   type Taft_Car is record
      Passenger_Count : Car_Passenger_Count;
   end record;

   type Car_Holder is new Any_Holder with record
      Car : aliased Taft_Car;
   end record;
   
   function Make_Holder return Any_Holder'Class is
   begin
      return C : Car_Holder do
         C.Car.Passenger_Count := 0;
      end return;
   end Make_Holder;

   function Allocate_Car (Holder : in out Any_Holder'Class) return Any_Car is
      H : Car_Holder renames Car_Holder (Holder);
   begin
      return Car : Any_Car (H.Car'Access) do
         null;
      end return;
   end Allocate_Car;

   function Passenger_Count (Car : Any_Car) return Car_Passenger_Count is
   begin
      return Car.Reference.Passenger_Count;
   end Passenger_Count;

   procedure Set_Passenger_Count
     (Car   : in out Any_Car;
      Value : Car_Passenger_Count) is
   begin
      Car.Reference.all.Passenger_Count := Value;
   end Set_Passenger_Count;
   
end Cars;

with Ada.Text_IO;

with Cars;
use  Cars;

procedure Main is
   Holder : Cars.Any_Holder'Class := Cars.Make_Holder;
   Car : Cars.Any_Car := Cars.Allocate_Car (Holder);
begin
   Set_Passenger_Count (Car, 3);
   Ada.Text_IO.Put_Line (Passenger_Count (Car)'Image);
end Main;

The issues with the above implementation is:
1. Usage of downward conversion at "H : Car_Holder renames Car_Holder (Holder);". It is a feature of Ada that can lead to inefficient code generation and there is a gnatcheck or AdaControl rule to check/forbid such usage.
2. Usage of anonymous access type "(Reference : not null access Taft_Car)". It isn't obvious from the code as it is written that it is correct although it is accepted by the GNAT compiler due to the complexity of the anonymous access type rules. Perhaps somebody in the Ada community would like to motivate using the anonymous access type rules in the Reference Manual why it is correct? :)

Best regards,
Joakim


  reply	other threads:[~2020-01-24  9:47 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-17 23:30 Calling a record type's methods (functions or procedure) when record is in an array Mace Ayres
2020-01-18 12:31 ` Simon Wright
2020-01-18 18:02 ` Mace Ayres
2020-01-18 20:53   ` Simon Wright
2020-01-21 20:51   ` Shark8
2020-01-21 23:17     ` Jeffrey R. Carter
2020-01-23 15:00     ` joakimds
2020-01-23 15:02       ` joakimds
2020-01-23 16:51         ` Simon Wright
2020-01-24  9:47           ` joakimds [this message]
2020-01-23 20:15       ` Optikos
2020-01-19 15:06 ` Mace Ayres
replies disabled

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