Использование псевдонимов в языке Ada

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;

Компилятор выдает ошибку при указанном выше назначении доступа, говоря, что нелокальному указателю нельзя присвоить локальное значение. Я не понимаю, почему возникла ошибка, потому что я только что определил тип в пакете, но фактический объект для доступа определяется только внутри локальной процедуры.

Я не ожидаю никакой ошибки, но в соответствии с языком это будет ошибка.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в том, что тип доступа определен на «уровне библиотеки» (в основном максимально возможный срок службы), тогда как переменная объявляется на более низком/более глубоком уровне внутри функции.

Ада запрещает присваивать объект более низкого/более глубокого уровня типу более высокого уровня, поскольку объект будет освобожден задолго до того, как тип доступа выйдет за пределы области видимости. Поскольку Ada может иметь некоторые правила автоматического освобождения, когда типы доступа выходят за пределы области действия (в некоторых случаях), язык запрещает присваивать объект с более низкой областью действия типу доступа с более высокой областью.

Он также обеспокоен тем, что вы потенциально можете создать объект типа доступа в более высокой области и передать ему этот объект типа локального доступа, что тогда означает, что объект более высокой области видимости будет висеть. (общий случай, который должен учитывать компилятор).

В вашем конкретном случае не будет никаких проблем, но компилятор должен учитывать общий случай.

Тем не менее, язык Ada определенно мог бы использовать более детальную переработку правил типов доступа, чтобы разрешить подобные ситуации. Это определенно технически возможно сделать в общем смысле, просто язык на данный момент не поддерживает это. Вы определенно можете внести предложение (проблему) в репозиторий входных данных сообщества пользователей GitHub группы Ada Докладчик (ARG): https://github.com/Ada-Rapporteur-Group/User-Community-Input

Со своей стороны вы можете сделать несколько вещей:

  1. Создайте локальный тип доступа внутри функции и присвойте объект переменной этого типа.
  2. Создайте ссылочный тип и присвойте ему переменную, он выполнит некоторые проверки во время выполнения в дополнение к проверкам во время компиляции.
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;

Большое спасибо за подробное объяснение, сэр.

Gumidelli Venkatesh 02.07.2024 17:42

Если вы используете GNAT, вы можете использовать непереносимый ’Unrestricted_Access.

Другие вопросы по теме