1

太いポインターの作成に問題があります。私の現在の一連の宣言は次のようになります。

type Index_Typ is mod 20; -- will be larger in real life
type Data_Buffer_Typ is array (Index_Typ range <>) of Integer; --unconstrained array type
type Data_Buffer_Ptr is access all Data_Buffer_Typ; -- a thick pointer, contains the bounds of array subtype pointed to and address..

Data_Buffer : aliased Data_Buffer_Typ (Index_Typ) := (others => 0); -- this is private
type Result_Typ is (Ok, Overflow, Null_Pointer);

   procedure Retrieve (Index    : in     Index_Typ;
                       Len      : in     Index_Typ;
                       Data_Ptr :    out Data_Buffer_Ptr;
                       Result   :    out Result_Typ) is
   begin
     -- assuming range checks are ok, what goes here ?
   end Retrieve;

だから私が宣言した場合:

Ptr : Data_Buffer_Ptr := null;

の呼び出しが与えられたRetreive (2,3, Ptr,Result);場合、要素 2、3、および 4 を指すポインターで終わる方法はData_Buffer?

ノート:

  • はい、とにかく配列スライスを渡すことはおそらくポインターとして行われることを知っていますが、暗黙的にではなく、明示的にポインターを使用したいと考えています (私の選択ではありません!)。
  • はい、実験しましたが、通常は : ( object subtype must statically match designated subtype) エラー メッセージが表示されます。
  • 可能な限り の使用はnew避けてください。
4

1 に答える 1

1

これは私にとってはうまくいきますが、反発的だと言わざるを得ません!のコンポーネントの順序に注意してくださいFat_Pointer。これは、私が始めたものとは逆であり、この64ビットマシンのレコードのサイズです(順序を明示するためにrep句を挿入しましたが、なくても正常に機能します)。また、私はあなたが立ち往生していると思いますnew

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;
with System;
procedure Fat is
   type Index_Typ is mod 20;
   type Data_Buffer_Typ is array (Index_Typ range <>) of Integer;
   type Data_Buffer_Ptr is access all Data_Buffer_Typ;
   Data_Buffer : aliased Data_Buffer_Typ (Index_Typ) := (others => 0);
   type Result_Typ is (Ok, Overflow, Null_Pointer);

   procedure Retrieve (Index    : in     Index_Typ;
                       Len      : in     Index_Typ;
                       Data_Ptr :    out Data_Buffer_Ptr;
                       Result   :    out Result_Typ)
   is
      type Bound is (Lower, Upper);
      type Bounds is array (Bound) of Index_Typ;
      type Bounds_P is access Bounds;
      type Fat_Pointer is record
         The_Data : System.Address;
         The_Bounds : Bounds_P;
      end record;
      for Fat_Pointer use record
         The_Data at 0 range 0 .. 63;
         The_Bounds at 8 range 0 .. 63;
      end record;
      function To_Data_Buffer_Ptr
      is new Ada.Unchecked_Conversion (Fat_Pointer, Data_Buffer_Ptr);
      Answer : constant Fat_Pointer
        := (The_Bounds => new Bounds'(Lower => Index,
                                      Upper => Index + Len - 1),
            The_Data => Data_Buffer (Index)'Address);
   begin
      Result := Ok;
      Data_Ptr := To_Data_Buffer_Ptr (Answer);
   end Retrieve;

   Ptr : Data_Buffer_Ptr := null;
   Result : Result_Typ;

begin
   for J in Data_Buffer'Range loop
      Data_Buffer (J) := Integer (J);
   end loop;

   Retrieve (2, 3, Ptr, Result);

   for J in Ptr'Range loop
      Put_Line (J'Img & " => " & Ptr (J)'Img);
   end loop;
end Fat;
于 2013-03-19T11:04:59.530 に答える