Ada RM compliance of the GNAT/gcc?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi folks,

I am writing an Ada package (an option processing package) that requires to pass an anonymous access to function type to a procedure, which will then store it in an array to be called later.

I have stumbled into a strange behaviour of the GNAT compiler (gnat --version: GNAT 12.2.0, Copyright (C) 1996-2022, Free Software Foundation, Inc.; installed using 'alr install --prefix=~/install/gnat-alire/gnat-alire-12.2' with alr 2.0-dev on Ubuntu-20.04):

1) when I compile the code (the 'process_options.adb' main procedure that uses the 'Get_Options' package) with the 'Is_Present' and other fields explicitly initialised ('Is_Present => False' at get_options.adb:24), everything compiles and runs as expected;

2) when I instead change to default initialisation ('Is_Present =><>' at get_options.adb:24, or remove the line altogether to rely on the 'others => <>' statement), I get the following error message from the compiler:

gcc -c -Iprograms/ -Isrc -gnata -I- -o /home/saulius/tests/ada/ada-pass-access-function/.obj/get_options.o /home/saulius/tests/ada/ada-pass-access-function/src/get_options.adb get_options.adb:20:29: error: illegal attempt to store anonymous access to subprogram get_options.adb:20:29: error: value has deeper accessibility than any master (RM 3.10.2 (13)) get_options.adb:20:29: error: use named access type for "Processor" instead of access parameter gnatmake: "/home/saulius/tests/ada/ada-pass-access-function/src/get_options.adb" compilation error

Is the behaviour of the GNAT compiler correct in both cases?

If yes, why the legality of the anonymous access procedure type assignment depends on the initialisation code of /other/ fields?

If not, which case is correct and will be retained in the future? (I have a bad feeling that the behaviour in (2) is correct and (1) is a compiler bug, although the behaviour in (1) fits neatly my purpose and seems to be totally safe in this particular case :) ...).

I attach what I see as a minimal working example abstracted from my code.

I will be grateful for any explanations, or any hint as to where to seek information (the mailing lists mentioned at http://sigada.org/resources.html#Google%20Groups are unfortunately mostly filled with spam and/or advertisements, seem to be unmoderated and unused).

Sincerely yours,
Saulius

--
Dr. Saulius Gražulis
Vilnius University Institute of Biotechnology, Saulėtekio al. 7
LT-10257 Vilnius, Lietuva (Lithuania)
fax: (+370-5)-2234367 / phone (office): (+370-5)-2234353
mobile: (+370-684)-49802, (+370-614)-36366

--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

with Text_IO; use Text_IO;

package body Get_Options is
   
   procedure Help (Option_String : String; Pos : Positive) is
   begin
      Put_Line ("This is a help from the package ...");
   end;
   
   function Option
     (
      Short_Option : String;
      Processor : access procedure
        (Option_String : String; Position : Positive)
     ) return Option_Type is
   begin
      return
        (
         Short_Option => Short_Option (Short_Option'First + 1),
         Value_Processor => Processor,
         -- Fails to compile if the folowing line, 'Is_Present =>
         --  False,', is commented out or changed to use the default
         --  initialisation ('Is_Present => <>'):
         Is_Present => <>,
         others => <>
        );
   end;
   
end Get_Options;
package Get_Options is
   
   type Option_Processor_Type is access procedure
     (Option_String : String; Position : Positive);

   type Option_Type is record
      Short_Option : Character;
      Value_Processor : Option_Processor_Type;
      Is_Present : Boolean := False;
   end record;
   
   type Option_Array is array (Positive range <>) of Option_Type;
   
   procedure Help (Option_String : String; Pos : Positive);
   
   function Option
     (
      Short_Option : String;
      Processor : access procedure
        (Option_String : String; Position : Positive)
     ) return Option_Type;
   
end Get_Options;
pragma Ada_2022;

with Text_IO; use Text_IO;
with Get_Options; use Get_Options;

procedure Process_Options is
   
   procedure Help (Option_String : String; Pos : Positive) is
   begin
      Put_Line ("This is a help from the main program ...");
   end;
   
   Options : Option_Array :=
     (
      Option ("-h", Help'Access),
      Option ("-H", Get_Options.Help'Access)
     );   
   
begin
   
   -- Options (1).Value_Processor := Get_Options.Help'Access; -- compiles and works
   -- Options (1).Value_Processor := Help'Access; -- fails at compile time
   
   for O of Options loop
      Put_Line (O.Short_Option'Image);
      Put_Line (O.Is_Present'Image);
      Put_Line (O.Value_Processor'Image);
      if O.Value_Processor /= null then
         O.Value_Processor ("--one", 1);
      end if;
   end loop;
   
end;

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux