3
Package pack1 is 

  Type int_acc_type is access all integer;

End pack1;

--Local procedure
with pack1;
Procedure main is

 Int_acc : pack1.int_acc_type;
 Int_var : aliased integer;

Begin
   Int_acc := Int_var'access;

End main;

Compiler is throwing error at above access assignment saying non-local pointer cannot be assigned with local value. I don't understand why the error because I just defined the type in package, but actual object for access is defined inside the local procedure only.

I expect no error, but as per language it will error.

2 Answers 2

6

The issue is that the Access type is defined at "library level" (basically highest lifetime possible) while the variable is declared at a lower/deeper level inside a function.

Ada forbids assigning a lower/deeper level object to a higher level type because the object will be deallocated long before the access type is out of scope. Since Ada can have some auto deallocation rules process when access types leave scope (in some cases), the language forbids assigning a lower scope object to a higher scope access type.

It also is worried that you could potentially create an access type object at higher scope and pass that local access type object to it, which then means that higher scope object would dangle. (general case the compiler has to consider).

In your specific case, there wouldn't be any issue, but the compiler needs to account for the general case.

That said, the Ada language could definitely use more fine grained access type rules overhaul to allow situations like this. It's definitely technically possible to do this in the general sense, the language just doesn't support it at this time. You can definitely make a suggestion (issue) at the Ada Rapporteur Group (ARG) github user community input repo: https://github.com/Ada-Rapporteur-Group/User-Community-Input

On your end, you can do a couple of things:

  1. Create a local access type inside the function and assign the object to a variable of that type.
  2. Create a reference type and assign the var to that, it'll do some runtime checks in addition to compile time checks.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure jdoodle is
    Package pack1 is 

      Type int_acc_type is access all integer;
      
      -- Reference type
      type int_acc_type2(Element : not null access Integer) is limited null record
         with Implicit_Dereference => Element;
    
    End pack1;
    
    Procedure main is
    
     Int_acc : pack1.int_acc_type;
     Int_var : aliased integer;
     
     Int_acc2 : pack1.int_acc_type2(Int_Var'Access);
     
     -- Local access type
     type int_acc_type3 is access all integer;
     
     Int_acc3 : int_acc_type3;
    
    Begin
       --Int_acc := Int_var'access;
       Int_acc3 := Int_var'Access;
       null;
    End main;
begin
    null;
end jdoodle;
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for your detailed explanation sir.
4

If you’re using GNAT, you can use the non-portable ’Unrestricted_Access.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.