How to make an access to a single element of an array using indefinite types

Hello,

I’m sure there is a simple solution, but i cannot find it for now.
I am using some indefinite types for the sake of flexibility.
My goal is just to have an access (pointer) of one element of a matrix, but i get the error “object subtype must statically match designated subtype”

package lib is

   type unconstrained is array (Positive range <>) of aliased Natural;
   type unconstrainedptr is access all unconstrained;
   
   type arrayconstrained is array (1..5) of aliased unconstrained ( 1 .. 3);
   type arrayconstrainedptr is access all arrayconstrained;   
  
   content_array : aliased arrayconstrained := ( 1 .. 5 => (others => 0));    
end lib;

with lib; use lib;
procedure Main is   
   miarrayptr : lib.arrayconstrainedptr := content_array'Access; -- This is ok
   miptr : lib.unconstrainedptr := content_array(2)'access; -- This Fail !!
begin
   null;
end Main;

BTW, there are proper 2D arrays in Ada. That is a simple solution.
Complex solution. You constrained the unconstrained array when you declared arrayconstrained. You cannot take a pointer to an unconstrained array from a constrained array. The reason for that is that the compiler does not store the array bounds (AKA array dope) for constrained arrays. The bounds are statically known, 1…3 in your case, and the array contains only its elements. A pointer to an unconstrained array expects bounds which are nowhere to get. The compiler message about subtypes that must statically match hints you. A constrained array subtype does not match the unconstrained one. You can fix that by declaring a subtype:

   subtype unconstrained_13 is unconstrained ( 1..3);
   type unconstrained_13_ptr is access all unconstrained_13;

and using it like:

   type arrayconstrained is array (1..5) of aliased unconstrained_13;

Now it will work.

1 Like

I don’t have a compiler here to test atm, but you can try type converting your access since unconstraintedptr is a general access type.

Try:
miptr : lib.unconstrainedptr := lib.unconstrainedptr(content_array(2)'access);

I’d try it myself, but I don’t have a way at this location, so I don’t know if it is a legal conversion or not.

No, it is illegal for the same reason. See ARM 34/2:

…Explicit conversion is allowed between general access types with matching designated subtypes;…

Ada is a well-designed language. It is difficult to shot yourself in the foot. You should try really hard. :slightly_smiling_face:

thank you dmitry, going with 2D array it’s the best workaround i’m testing