Как сделать размер универсального типа явным в Аде?

Я пытаюсь скомпилировать этот код: https://github.com/RanaExMachina/ada-fuse

К сожалению, при сборке я получаю эту ошибку:

fuse-system.ads:147:04: size clause not allowed for variable length type

Это кажется проблемой, потому что в коде он пытается установить размер записи, которая имеет общий тип в качестве записи. Кажется, это новая ошибка, поскольку у разработчика не было этой проблемы, когда он писал это 2,5 года назад. К сожалению, он не может помочь мне в кратчайшие сроки, но я должен запустить эту библиотеку. Однако я немного беспомощен в решении этой проблемы.

По сути, мне кажется, что я должен каким-то образом сообщить комару, насколько большим будет этот тип, который, вопреки убеждению комара, априори известен: это тип доступа. Либо в record, либо в определении универсального типа.

Соответствующие части:

fuse-main.ads:
  package Fuse.Main is
    package IO is
      new Ada.Direct_IO (Element_Type);
    type File_Access is access IO.File_Type;

fuse-system.ads:
  generic
    type File_Access is private;
  package Fuse.System is
  ...
    type File_Info_Type is record
      Flags       : Flags_Type;
      Fh_Old      : Interfaces.C.unsigned_long;
      Writepage   : Interfaces.C.int;
      Direct_IO   : Boolean := True;
      Keep_Cache  : Boolean := True;
      Flush       : Boolean := True;
      Nonseekable : Boolean := True;
      Fh          : File_Access;
      Lock_Owner  : Interfaces.Unsigned_64;
    end record;
  type File_Info_Access is access File_Info_Type;
  pragma Convention (C, File_Info_Type);
  for File_Info_Type'Size use 32*8;

Моя версия комара: 4.9.2-1 (debian jessie)


person alex    schedule 11.11.2015    source источник


Ответы (1)


Вы знаете, что File_Access — это тип доступа, но внутри Fuse.System компилятор этого не знает; все, что он знает, это то, что он определен и поддерживает присваивание и равенство. Фактические могут быть сотни байтов.

Чтобы сообщить компилятору, что это является типом доступа, попробуйте что-то вроде этого (я сжал его в один пакет для своего удобства в Mac OS X, поэтому размер указателя 64-битный; компилируется нормально) :

with Ada.Text_IO;
package Fuse_Tests is

   generic
      type File_Type is limited private;
      type File_Access is access File_Type;
   package Fuse_System is
      type File_Info_Type is record
         Fh : File_Access;
      end record;
      for File_Info_Type'Size use 64;
   end Fuse_System;

   type File_Access is access Ada.Text_IO.File_Type;

   package My_Fuse_System is new Fuse_System
     (File_Type   => Ada.Text_IO.File_Type,
      File_Access => File_Access);

end Fuse_Tests;

Или альтернатива, предложенная в комментариях:

with Ada.Text_IO;
package Fuse_Tests is

   generic
      type File_Type;
   package Fuse_System is
      type File_Access is access File_Type;
      type File_Info_Type is record
         Fh : File_Access;
      end record;
      for File_Info_Type'Size use 64;
   end Fuse_System;

   package My_Fuse_System is new Fuse_System
     (File_Type => Ada.Text_IO.File_Type);

   --  if needed ...
   subtype File_Access is My_Fuse_System.File_Access;

end Fuse_Tests;
person Simon Wright    schedule 11.11.2015
comment
Интересно, имеет ли смысл (или вообще полезно) сделать здесь File неполным типом. Я думаю, что я бы попробовал это и определил тип доступа в самом дженерике, чтобы дженерик можно было создать в той же общедоступной части, где объявлен фактический файл. - person manuBriot; 11.11.2015