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;
Компилятор выдает ошибку при указанном выше назначении доступа, говоря, что нелокальному указателю нельзя присвоить локальное значение. Я не понимаю, почему возникла ошибка, потому что я только что определил тип в пакете, но фактический объект для доступа определяется только внутри локальной процедуры.
Я не ожидаю никакой ошибки, но в соответствии с языком это будет ошибка.
Проблема в том, что тип доступа определен на «уровне библиотеки» (в основном максимально возможный срок службы), тогда как переменная объявляется на более низком/более глубоком уровне внутри функции.
Ада запрещает присваивать объект более низкого/более глубокого уровня типу более высокого уровня, поскольку объект будет освобожден задолго до того, как тип доступа выйдет за пределы области видимости. Поскольку Ada может иметь некоторые правила автоматического освобождения, когда типы доступа выходят за пределы области действия (в некоторых случаях), язык запрещает присваивать объект с более низкой областью действия типу доступа с более высокой областью.
Он также обеспокоен тем, что вы потенциально можете создать объект типа доступа в более высокой области и передать ему этот объект типа локального доступа, что тогда означает, что объект более высокой области видимости будет висеть. (общий случай, который должен учитывать компилятор).
В вашем конкретном случае не будет никаких проблем, но компилятор должен учитывать общий случай.
Тем не менее, язык Ada определенно мог бы использовать более детальную переработку правил типов доступа, чтобы разрешить подобные ситуации. Это определенно технически возможно сделать в общем смысле, просто язык на данный момент не поддерживает это. Вы определенно можете внести предложение (проблему) в репозиторий входных данных сообщества пользователей GitHub группы Ada Докладчик (ARG): https://github.com/Ada-Rapporteur-Group/User-Community-Input
Со своей стороны вы можете сделать несколько вещей:
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;
Если вы используете GNAT, вы можете использовать непереносимый ’Unrestricted_Access
.
Большое спасибо за подробное объяснение, сэр.