Различия при использовании процедур анонимного доступа или типов процедур доступа - PullRequest
5 голосов
/ 17 июня 2020

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

На данный момент у меня есть проблема с вложенными процедурами, в которых компилятор выдает мне ошибку, которую я не могу понять: subprogram must not be deeper than access type. Эта ошибка возникает, когда я объявил тип, который является доступом к процедуре, однако он работает безупречно при использовании параметра анонимного доступа, как показано в следующем MWE:

procedure Generaltest is
   type T_Access_Procedure is access procedure;

   procedure Test_Access (Proc : access procedure) is
   begin
      null;
   end Test_Access;

   procedure Test_Type (Proc : in T_Access_Procedure) is
   begin
      null;
   end Test_Type;

   procedure Test is
      procedure Nested_Procedure is
      begin
         null;
      end;

      -- Not allowed; subprogram must not bee deeper than access procedure.
      Proc : T_Access_Procedure := Nested_Procedure'Access;

   begin
      Test_Access (Nested_Procedure'Access); -- This line works fine.
      Test_Type (Nested_Procedure'Access);   -- This line also generates the error.
   end Test;

begin
   Test;
end Generaltest;

С моей точки зрения , это можно интерпретировать по-разному, в зависимости от акцента; подпрограмма не должна быть глубже, чем тип доступа или, подпрограмма не должна быть глубже, чем тип доступа . Другими словами, ошибка связана с самой подпрограммой или с типом параметра? Я склонен полагать, что это первое, поскольку подпрограмма является типом доступа, но я определенно не уверен.

Может ли кто-нибудь объяснить мне, в чем реальная разница между использованием типа в качестве параметра или использованием в этом смысле, и почему первый считается «глубже»?

В моем мире использование типа T_Access_Procedure в качестве параметра in является более элегантным способом сделать это, особенно если мои Выбранная процедура должна использоваться во многих процедурах или если у нее есть длинный список аргументов.

Ответы [ 2 ]

5 голосов
/ 18 июня 2020

Как описано в Обоснование Ada 95, 3.7.2 Доступ к подпрограммам , «Правила доступности во время компиляции гарантируют, что подпрограмма, обозначенная значением доступа, не может быть вызвана после того, как завершилась его охватывающая область ". В вашем примере значение доступа, ссылающееся на Nested_Procedure, действительно только в пределах области Test, но значение типа T_Access_Procedure может использоваться для вызова Nested_Procedure вне объем Test. И Proc, и фактический параметр, переданный в Test_Type, имеют тип T_Access_Procedure; ни один из них не разрешен.

Определенная c альтернатива зависит от того, что вы хотите сделать. Может быть полезно посмотреть Обоснование для Ada 2012, итерация 6.3 . Как обсуждалось здесь , «Формальные подпрограммы Generi c остаются наиболее общим средством параметризации алгоритма произвольной внешней подпрограммой».

4 голосов
/ 18 июня 2020

Разница преднамеренная. Как объяснил trashgod, с именованным типом доступа можно сохранить значение доступа и вызвать его позже, а правила предназначены для предотвращения сохранения значения, которое в противном случае могло бы быть вызвано, когда оно недействительно. Параметры анонимного доступа к подпрограмме, с другой стороны, не могут быть сохранены, что позволяет передавать любую подпрограмму.

...