comp.lang.ada
 help / color / mirror / Atom feed
* Type in allocator has deeper level than designated class-wide type
@ 2011-06-13 15:31 Adrian Hoe
  2011-06-13 17:11 ` Adam Beneschan
  0 siblings, 1 reply; 12+ messages in thread
From: Adrian Hoe @ 2011-06-13 15:31 UTC (permalink / raw)


Hi all,

I have stomped into above error and I am stuck with the error and
runtime exception PROGRAM_ERROR : accessibility check failed.

Here's the fragment of my codes:


generic
   N : Positive;
   type Item is private;
package High_Cloud is

   package List renames Heterogeneous_Doubly_Link_List;
   use List;


   type Data_Array               is array ( 1 .. N ) of Item;

   type Element_Record           is new List.Node with private;
   type Series_Access            is new List.Access_List;

private

   type Element_Record is new List.Node with
      record
         Name           : Unbounded_String;
         Color          : Unbounded_String;
         Data           : Data_Array;
      end record;

...
end High_Cloud;

In the package body of High_Cloud, I have a procedure:


   procedure Add
      ( Cloud          : in out High_Cloud_Record;
        Name            : in     Unbounded_String;
        Color           : in     Unbounded_String;
        Data            : in     Data_Array )
   is

      New_Element : List.Access_Node;

   begin

      New_Element := new Element_Record'
<========== Error/Warning here.
                        ( Constructor.Init ( Name, Color, Data) ) ;

      Concatenate ( Cloud.Series, New_Element ) ;

   end Add;


My intention is to use genericity to create a data which is an array
(1..N) of any_type. This data is then stored in a list. Procedure Add
instantiate (by calling to Constructor.Init) the list's node with
data.

I have read the ARM 3.10.2 and 3.10.1 and also John Barnes book yet I
still have no clue how to solve the problem.

Can you please help? Thanks.
--
Adrian Hoe
http://adrianhoe.com/adrianhoe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-13 15:31 Type in allocator has deeper level than designated class-wide type Adrian Hoe
@ 2011-06-13 17:11 ` Adam Beneschan
  2011-06-14  0:49   ` Adrian Hoe
  2011-06-14  1:07   ` Adrian Hoe
  0 siblings, 2 replies; 12+ messages in thread
From: Adam Beneschan @ 2011-06-13 17:11 UTC (permalink / raw)


On Jun 13, 8:31 am, Adrian Hoe <aby...@gmail.com> wrote:
> Hi all,
>
> I have stomped into above error and I am stuck with the error and
> runtime exception PROGRAM_ERROR : accessibility check failed.
>
> Here's the fragment of my codes:
>
> generic
>    N : Positive;
>    type Item is private;
> package High_Cloud is
>
>    package List renames Heterogeneous_Doubly_Link_List;
>    use List;
>
>    type Data_Array               is array ( 1 .. N ) of Item;
>
>    type Element_Record           is new List.Node with private;
>    type Series_Access            is new List.Access_List;
>
> private
>
>    type Element_Record is new List.Node with
>       record
>          Name           : Unbounded_String;
>          Color          : Unbounded_String;
>          Data           : Data_Array;
>       end record;
>
> ...
> end High_Cloud;
>
> In the package body of High_Cloud, I have a procedure:
>
>    procedure Add
>       ( Cloud          : in out High_Cloud_Record;
>         Name            : in     Unbounded_String;
>         Color           : in     Unbounded_String;
>         Data            : in     Data_Array )
>    is
>
>       New_Element : List.Access_Node;
>
>    begin
>
>       New_Element := new Element_Record'
> <========== Error/Warning here.
>                         ( Constructor.Init ( Name, Color, Data) ) ;
>
>       Concatenate ( Cloud.Series, New_Element ) ;
>
>    end Add;
>
> My intention is to use genericity to create a data which is an array
> (1..N) of any_type. This data is then stored in a list. Procedure Add
> instantiate (by calling to Constructor.Init) the list's node with
> data.
>
> I have read the ARM 3.10.2 and 3.10.1 and also John Barnes book yet I
> still have no clue how to solve the problem.
>
> Can you please help? Thanks.

I think we need to see the definition of Constructor.Init, at least.
(I'm guessing that Heterogeneous_Doubly_Link_List is a library package
that defines Node as a tagged record and Access_Node as "access all
Node'Class".  But I don't have a guess about what Init is.)

                               -- Adam



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-13 17:11 ` Adam Beneschan
@ 2011-06-14  0:49   ` Adrian Hoe
  2011-06-14  1:08     ` Adam Beneschan
  2011-06-14  1:07   ` Adrian Hoe
  1 sibling, 1 reply; 12+ messages in thread
From: Adrian Hoe @ 2011-06-14  0:49 UTC (permalink / raw)


On Jun 14, 1:11 am, Adam Beneschan <a...@irvine.com> wrote:
> On Jun 13, 8:31 am, Adrian Hoe <aby...@gmail.com> wrote:
>
>
>
>
>
> > Hi all,
>
> > I have stomped into above error and I am stuck with the error and
> > runtime exception PROGRAM_ERROR : accessibility check failed.
>
> > Here's the fragment of my codes:
>
> > generic
> >    N : Positive;
> >    type Item is private;
> > package High_Cloud is
>
> >    package List renames Heterogeneous_Doubly_Link_List;
> >    use List;
>
> >    type Data_Array               is array ( 1 .. N ) of Item;
>
> >    type Element_Record           is new List.Node with private;
> >    type Series_Access            is new List.Access_List;
>
> > private
>
> >    type Element_Record is new List.Node with
> >       record
> >          Name           : Unbounded_String;
> >          Color          : Unbounded_String;
> >          Data           : Data_Array;
> >       end record;
>
> > ...
> > end High_Cloud;
>
> > In the package body of High_Cloud, I have a procedure:
>
> >    procedure Add
> >       ( Cloud          : in out High_Cloud_Record;
> >         Name            : in     Unbounded_String;
> >         Color           : in     Unbounded_String;
> >         Data            : in     Data_Array )
> >    is
>
> >       New_Element : List.Access_Node;
>
> >    begin
>
> >       New_Element := new Element_Record'
> > <========== Error/Warning here.
> >                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> >       Concatenate ( Cloud.Series, New_Element ) ;
>
> >    end Add;
>
> > My intention is to use genericity to create a data which is an array
> > (1..N) of any_type. This data is then stored in a list. Procedure Add
> > instantiate (by calling to Constructor.Init) the list's node with
> > data.
>
> > I have read the ARM 3.10.2 and 3.10.1 and also John Barnes book yet I
> > still have no clue how to solve the problem.
>
> > Can you please help? Thanks.
>
> I think we need to see the definition of Constructor.Init, at least.
> (I'm guessing that Heterogeneous_Doubly_Link_List is a library package
> that defines Node as a tagged record and Access_Node as "access all
> Node'Class".  But I don't have a guess about what Init is.)
>
>                                -- Adam


Yes, you are right. In Heterogeneous_Doubly_Link_List:


   type List        is limited private;
   type Access_List is access List;

   type Node           is tagged private;
   type Access_Node   is access all Node'Class;


private

   type Node is tagged record
      Previous : Access_Node;
      Next     : Access_Node;
   end record;

   type List is limited record
      Head    : Access_Node := null;
      Tail    : Access_Node := null;
      Current : Access_Node := null;
      Count   : Unsigned := 0;
   end record;


And:


   package body Constructor is

      function Init
         ( New_Name  : Unbounded_String;
           New_Color : Unbounded_String;
           New_Data  : Data_Array )
      return Element_Record is
      begin
         return ( List.Constructor.Init
                     with
                        Name  => New_Name,
                        Color => New_Color,
                        Data  => New_Data
                ) ;
      end Init;

   end Constructor;

Is the problem lying in the Data : Data_Array in Element_Record or in
the return statement of Constructor.Init?



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-13 17:11 ` Adam Beneschan
  2011-06-14  0:49   ` Adrian Hoe
@ 2011-06-14  1:07   ` Adrian Hoe
  2011-06-14  1:24     ` Adam Beneschan
  1 sibling, 1 reply; 12+ messages in thread
From: Adrian Hoe @ 2011-06-14  1:07 UTC (permalink / raw)


On Jun 14, 1:11 am, Adam Beneschan <a...@irvine.com> wrote:
> On Jun 13, 8:31 am, Adrian Hoe <aby...@gmail.com> wrote:
>
>
>
>
>
> > Hi all,
>
> > I have stomped into above error and I am stuck with the error and
> > runtime exception PROGRAM_ERROR : accessibility check failed.
>
> > Here's the fragment of my codes:
>
> > generic
> >    N : Positive;
> >    type Item is private;
> > package High_Cloud is
>
> >    package List renames Heterogeneous_Doubly_Link_List;
> >    use List;
>
> >    type Data_Array               is array ( 1 .. N ) of Item;
>
> >    type Element_Record           is new List.Node with private;
> >    type Series_Access            is new List.Access_List;
>
> > private
>
> >    type Element_Record is new List.Node with
> >       record
> >          Name           : Unbounded_String;
> >          Color          : Unbounded_String;
> >          Data           : Data_Array;
> >       end record;
>
> > ...
> > end High_Cloud;
>
> > In the package body of High_Cloud, I have a procedure:
>
> >    procedure Add
> >       ( Cloud          : in out High_Cloud_Record;
> >         Name            : in     Unbounded_String;
> >         Color           : in     Unbounded_String;
> >         Data            : in     Data_Array )
> >    is
>
> >       New_Element : List.Access_Node;
>
> >    begin
>
> >       New_Element := new Element_Record'
> > <========== Error/Warning here.
> >                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> >       Concatenate ( Cloud.Series, New_Element ) ;
>
> >    end Add;
>
> > My intention is to use genericity to create a data which is an array
> > (1..N) of any_type. This data is then stored in a list. Procedure Add
> > instantiate (by calling to Constructor.Init) the list's node with
> > data.
>
> > I have read the ARM 3.10.2 and 3.10.1 and also John Barnes book yet I
> > still have no clue how to solve the problem.
>
> > Can you please help? Thanks.
>
> I think we need to see the definition of Constructor.Init, at least.
> (I'm guessing that Heterogeneous_Doubly_Link_List is a library package
> that defines Node as a tagged record and Access_Node as "access all
> Node'Class".  But I don't have a guess about what Init is.)
>
>                                -- Adam


I changed the line in procedure Add from


      New_Element := new Element_Record'
                        ( Constructor.Init ( Name, Color, Data) ) ;

to

      New_Element := new Element_Record;

The compiler is still pointing the same warning to this line.

What exactly does the warning message "Type in allocator has deeper
level than designated class-wide type" mean? Is the compiler unable to
determine the size of the array during allocation? Or the array is a
level deeper than the List.Access_Node?

Thanks.

--
Adrian Hoe
http://adrianhoe.com/adrianhoe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14  0:49   ` Adrian Hoe
@ 2011-06-14  1:08     ` Adam Beneschan
  2011-06-14  1:11       ` Adrian Hoe
  0 siblings, 1 reply; 12+ messages in thread
From: Adam Beneschan @ 2011-06-14  1:08 UTC (permalink / raw)


On Jun 13, 5:49 pm, Adrian Hoe <aby...@gmail.com> wrote:
> On Jun 14, 1:11 am, Adam Beneschan <a...@irvine.com> wrote:
>
>
>
>
>
> > On Jun 13, 8:31 am, Adrian Hoe <aby...@gmail.com> wrote:
>
> > > Hi all,
>
> > > I have stomped into above error and I am stuck with the error and
> > > runtime exception PROGRAM_ERROR : accessibility check failed.
>
> > > Here's the fragment of my codes:
>
> > > generic
> > >    N : Positive;
> > >    type Item is private;
> > > package High_Cloud is
>
> > >    package List renames Heterogeneous_Doubly_Link_List;
> > >    use List;
>
> > >    type Data_Array               is array ( 1 .. N ) of Item;
>
> > >    type Element_Record           is new List.Node with private;
> > >    type Series_Access            is new List.Access_List;
>
> > > private
>
> > >    type Element_Record is new List.Node with
> > >       record
> > >          Name           : Unbounded_String;
> > >          Color          : Unbounded_String;
> > >          Data           : Data_Array;
> > >       end record;
>
> > > ...
> > > end High_Cloud;
>
> > > In the package body of High_Cloud, I have a procedure:
>
> > >    procedure Add
> > >       ( Cloud          : in out High_Cloud_Record;
> > >         Name            : in     Unbounded_String;
> > >         Color           : in     Unbounded_String;
> > >         Data            : in     Data_Array )
> > >    is
>
> > >       New_Element : List.Access_Node;
>
> > >    begin
>
> > >       New_Element := new Element_Record'
> > > <========== Error/Warning here.
> > >                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> > >       Concatenate ( Cloud.Series, New_Element ) ;
>
> > >    end Add;
>
> > > My intention is to use genericity to create a data which is an array
> > > (1..N) of any_type. This data is then stored in a list. Procedure Add
> > > instantiate (by calling to Constructor.Init) the list's node with
> > > data.
>
> > > I have read the ARM 3.10.2 and 3.10.1 and also John Barnes book yet I
> > > still have no clue how to solve the problem.
>
> > > Can you please help? Thanks.
>
> > I think we need to see the definition of Constructor.Init, at least.
> > (I'm guessing that Heterogeneous_Doubly_Link_List is a library package
> > that defines Node as a tagged record and Access_Node as "access all
> > Node'Class".  But I don't have a guess about what Init is.)
>
> >                                -- Adam
>
> Yes, you are right. In Heterogeneous_Doubly_Link_List:
>
>    type List        is limited private;
>    type Access_List is access List;
>
>    type Node           is tagged private;
>    type Access_Node   is access all Node'Class;
>
> private
>
>    type Node is tagged record
>       Previous : Access_Node;
>       Next     : Access_Node;
>    end record;
>
>    type List is limited record
>       Head    : Access_Node := null;
>       Tail    : Access_Node := null;
>       Current : Access_Node := null;
>       Count   : Unsigned := 0;
>    end record;
>
> And:
>
>    package body Constructor is
>
>       function Init
>          ( New_Name  : Unbounded_String;
>            New_Color : Unbounded_String;
>            New_Data  : Data_Array )
>       return Element_Record is
>       begin
>          return ( List.Constructor.Init
>                      with
>                         Name  => New_Name,
>                         Color => New_Color,
>                         Data  => New_Data
>                 ) ;
>       end Init;
>
>    end Constructor;
>
> Is the problem lying in the Data : Data_Array in Element_Record or in
> the return statement of Constructor.Init?

Where is the above Constructor package defined?  Is it directly within
High_Cloud, or is it defined inside a subprogram in the body of
High_Cloud?

Assuming it's the former, I can't get either our compiler or GNAT
(4.5.2) to generate an error or warning message.  However, I don't
know if any relevant rules about accessibility have changed in Ada
2012.  I'd have to study this one further.  If you're not using our
compiler or GNAT, and it's an Ada 2005 compiler, it could well be an
error in your compiler.

                               -- Adam



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14  1:08     ` Adam Beneschan
@ 2011-06-14  1:11       ` Adrian Hoe
  0 siblings, 0 replies; 12+ messages in thread
From: Adrian Hoe @ 2011-06-14  1:11 UTC (permalink / raw)


On Jun 14, 9:08 am, Adam Beneschan <a...@irvine.com> wrote:
> On Jun 13, 5:49 pm, Adrian Hoe <aby...@gmail.com> wrote:
>
>
>
>
>
> > On Jun 14, 1:11 am, Adam Beneschan <a...@irvine.com> wrote:
>
> > > On Jun 13, 8:31 am, Adrian Hoe <aby...@gmail.com> wrote:
>
> > > > Hi all,
>
> > > > I have stomped into above error and I am stuck with the error and
> > > > runtime exception PROGRAM_ERROR : accessibility check failed.
>
> > > > Here's the fragment of my codes:
>
> > > > generic
> > > >    N : Positive;
> > > >    type Item is private;
> > > > package High_Cloud is
>
> > > >    package List renames Heterogeneous_Doubly_Link_List;
> > > >    use List;
>
> > > >    type Data_Array               is array ( 1 .. N ) of Item;
>
> > > >    type Element_Record           is new List.Node with private;
> > > >    type Series_Access            is new List.Access_List;
>
> > > > private
>
> > > >    type Element_Record is new List.Node with
> > > >       record
> > > >          Name           : Unbounded_String;
> > > >          Color          : Unbounded_String;
> > > >          Data           : Data_Array;
> > > >       end record;
>
> > > > ...
> > > > end High_Cloud;
>
> > > > In the package body of High_Cloud, I have a procedure:
>
> > > >    procedure Add
> > > >       ( Cloud          : in out High_Cloud_Record;
> > > >         Name            : in     Unbounded_String;
> > > >         Color           : in     Unbounded_String;
> > > >         Data            : in     Data_Array )
> > > >    is
>
> > > >       New_Element : List.Access_Node;
>
> > > >    begin
>
> > > >       New_Element := new Element_Record'
> > > > <========== Error/Warning here.
> > > >                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> > > >       Concatenate ( Cloud.Series, New_Element ) ;
>
> > > >    end Add;
>
> > > > My intention is to use genericity to create a data which is an array
> > > > (1..N) of any_type. This data is then stored in a list. Procedure Add
> > > > instantiate (by calling to Constructor.Init) the list's node with
> > > > data.
>
> > > > I have read the ARM 3.10.2 and 3.10.1 and also John Barnes book yet I
> > > > still have no clue how to solve the problem.
>
> > > > Can you please help? Thanks.
>
> > > I think we need to see the definition of Constructor.Init, at least.
> > > (I'm guessing that Heterogeneous_Doubly_Link_List is a library package
> > > that defines Node as a tagged record and Access_Node as "access all
> > > Node'Class".  But I don't have a guess about what Init is.)
>
> > >                                -- Adam
>
> > Yes, you are right. In Heterogeneous_Doubly_Link_List:
>
> >    type List        is limited private;
> >    type Access_List is access List;
>
> >    type Node           is tagged private;
> >    type Access_Node   is access all Node'Class;
>
> > private
>
> >    type Node is tagged record
> >       Previous : Access_Node;
> >       Next     : Access_Node;
> >    end record;
>
> >    type List is limited record
> >       Head    : Access_Node := null;
> >       Tail    : Access_Node := null;
> >       Current : Access_Node := null;
> >       Count   : Unsigned := 0;
> >    end record;
>
> > And:
>
> >    package body Constructor is
>
> >       function Init
> >          ( New_Name  : Unbounded_String;
> >            New_Color : Unbounded_String;
> >            New_Data  : Data_Array )
> >       return Element_Record is
> >       begin
> >          return ( List.Constructor.Init
> >                      with
> >                         Name  => New_Name,
> >                         Color => New_Color,
> >                         Data  => New_Data
> >                 ) ;
> >       end Init;
>
> >    end Constructor;
>
> > Is the problem lying in the Data : Data_Array in Element_Record or in
> > the return statement of Constructor.Init?
>
> Where is the above Constructor package defined?  Is it directly within
> High_Cloud, or is it defined inside a subprogram in the body of
> High_Cloud?
>
> Assuming it's the former, I can't get either our compiler or GNAT
> (4.5.2) to generate an error or warning message.  However, I don't
> know if any relevant rules about accessibility have changed in Ada
> 2012.  I'd have to study this one further.  If you're not using our
> compiler or GNAT, and it's an Ada 2005 compiler, it could well be an
> error in your compiler.
>
>                                -- Adam



Yes, it is directly within High_Cloud.

I am using GNATMAKE  4.4.0 20080314 on Mac OS X 10.5.8, Xcode 3.0.

--
Adrian Hoe
http://adrianhoe.com/adrianhoe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14  1:07   ` Adrian Hoe
@ 2011-06-14  1:24     ` Adam Beneschan
  2011-06-14  6:04       ` Adrian Hoe
  0 siblings, 1 reply; 12+ messages in thread
From: Adam Beneschan @ 2011-06-14  1:24 UTC (permalink / raw)


On Jun 13, 6:07 pm, Adrian Hoe <aby...@gmail.com> wrote:

> I changed the line in procedure Add from
>
>       New_Element := new Element_Record'
>                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> to
>
>       New_Element := new Element_Record;
>
> The compiler is still pointing the same warning to this line.
>
> What exactly does the warning message "Type in allocator has deeper
> level than designated class-wide type" mean? Is the compiler unable to
> determine the size of the array during allocation? Or the array is a
> level deeper than the List.Access_Node?

It has nothing to do with arrays.  When you declare a type as "access
all T'Class", an object of that type can't be made to point to a type
declared in a more deeply nested subprogram.  A simple example:

package Pack1 is
    type Root is tagged null record;
    type Acc is access all Root'Class;
end Pack1;

package Pack2 is
    procedure Proc1;
end Pack2;

with Pack1;
package body Pack2 is
    procedure Proc1 is
        type Child is new Pack1.Root with null record;
        A : Pack1.Acc;
    begin
        A := new Child;   -- ILLEGAL
    end Proc1;
end Pack2;

This assignment statement is illegal, because somewhere later, A could
be copied to, say, another variable of type Pack1.Acc declared
globally in the body of Pack2, and then you'd have a pointer to a
Child that would exist after Proc1 has exited and the Child type no
longer exists, which is a big no-no.  4.8(5.1) prohibits this.

Since in this case, the record type (Element_Record) is declared in a
generic, that complicates things, because the generic *could* be
instantiated inside a procedure, which would lead to the same sort of
problem as above.  I don't remember all the rules, but depending on
where the type is declared and where the allocator occurs (generic
specification or body), it might be illegal to instantiate this
generic inside a procedure, or it might cause Program_Error to be
raised.  I just tried our compiler again and modified the source to
instantiate High_Cloud; if there's an instance of High_Cloud inside a
procedure, it *does* give a warning that Program_Error will be raised
(if the "new Element_Record" expression is reached).  If your compiler
gives the warning when the generic is first seen, before an instance
of the generic is seen, that's just a choice your compiler makes.  But
unless your program is arranged in a different order than I'm
guessing, or unless there are some new Ada 2012 rules that I'm not yet
familiar with, the compiler should not reject your generic, and it
should not reject it or cause Program_Error to be raised if there's an
instance of the generic that is *not* inside a subprogram.

                                  -- Adam



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14  1:24     ` Adam Beneschan
@ 2011-06-14  6:04       ` Adrian Hoe
  2011-06-14  8:01         ` Adrian Hoe
  0 siblings, 1 reply; 12+ messages in thread
From: Adrian Hoe @ 2011-06-14  6:04 UTC (permalink / raw)


On Jun 14, 9:24 am, Adam Beneschan <a...@irvine.com> wrote:
> On Jun 13, 6:07 pm, Adrian Hoe <aby...@gmail.com> wrote:
>
> > I changed the line in procedure Add from
>
> >       New_Element := new Element_Record'
> >                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> > to
>
> >       New_Element := new Element_Record;
>
> > The compiler is still pointing the same warning to this line.
>
> > What exactly does the warning message "Type in allocator has deeper
> > level than designated class-wide type" mean? Is the compiler unable to
> > determine the size of the array during allocation? Or the array is a
> > level deeper than the List.Access_Node?
>
> It has nothing to do with arrays.  When you declare a type as "access
> all T'Class", an object of that type can't be made to point to a type
> declared in a more deeply nested subprogram.  A simple example:
>
> package Pack1 is
>     type Root is tagged null record;
>     type Acc is access all Root'Class;
> end Pack1;
>
> package Pack2 is
>     procedure Proc1;
> end Pack2;
>
> with Pack1;
> package body Pack2 is
>     procedure Proc1 is
>         type Child is new Pack1.Root with null record;
>         A : Pack1.Acc;
>     begin
>         A := new Child;   -- ILLEGAL
>     end Proc1;
> end Pack2;
>
> This assignment statement is illegal, because somewhere later, A could
> be copied to, say, another variable of type Pack1.Acc declared
> globally in the body of Pack2, and then you'd have a pointer to a
> Child that would exist after Proc1 has exited and the Child type no
> longer exists, which is a big no-no.  4.8(5.1) prohibits this.
>
> Since in this case, the record type (Element_Record) is declared in a
> generic, that complicates things, because the generic *could* be
> instantiated inside a procedure, which would lead to the same sort of
> problem as above.  I don't remember all the rules, but depending on
> where the type is declared and where the allocator occurs (generic
> specification or body), it might be illegal to instantiate this
> generic inside a procedure, or it might cause Program_Error to be
> raised.  I just tried our compiler again and modified the source to
> instantiate High_Cloud; if there's an instance of High_Cloud inside a
> procedure, it *does* give a warning that Program_Error will be raised
> (if the "new Element_Record" expression is reached).  If your compiler
> gives the warning when the generic is first seen, before an instance
> of the generic is seen, that's just a choice your compiler makes.  But
> unless your program is arranged in a different order than I'm
> guessing, or unless there are some new Ada 2012 rules that I'm not yet
> familiar with, the compiler should not reject your generic, and it
> should not reject it or cause Program_Error to be raised if there's an
> instance of the generic that is *not* inside a subprogram.
>
>                                   -- Adam


I see and I followed this post by Robert Duff:
https://groups.google.com/group/comp.lang.ada/browse_frm/thread/8fc030c3b6c79517/45208b566c079110?lnk=gst&q=generic+and+accessibility#45208b566c079110

Hence,


generic
   type Index is ( <> ) ;
   type Item is private;
package High_Cloud is

   package List renames Heterogeneous_Doubly_Link_List;
   use List;

   type Element_Record           is new List.Node with private;
   type Series_Access            is new List.Access_List;
private
   type Element_Record is new List.Node with
      record
         Name           : Unbounded_String;
         Color          : Unbounded_String;
         Data           : Item;
      end record;
...
end High_Cloud;
In the package body of High_Cloud, I have a procedure:
   procedure Add
      ( Cloud          : in out High_Cloud_Record;
        Name            : in     Unbounded_String;
        Color           : in     Unbounded_String;
        Data            : in     Item )
   is
      New_Element : List.Access_Node;
   begin
      New_Element := new Element_Record'
                        ( Constructor.Init ( Name, Color, Data) ) ;
      Concatenate ( Cloud.Series, New_Element ) ;
   end Add;

To use High_Cloud:


with High_Cloud;

package Hen is

   type I_Array is array ( 1 .. 31 ) of Integer;
   package G is new High_Cloud ( Positive, I_Array ) ;
   use G;

end Hen;



and in the procedure, I have:


with High_Cloud;
with Hen;

procedure smalltest is


   package H renames Hen;
   use H;

   Data_Op : H.I_Array := ( 3, 4, 2, 3, 3, 3, 0, 3, 6, 3, 2, 6, 8, 7,
                            3, 4, 3, 5, 1, 3, 1, 2, 2, 0, 2, 6, 8, 7,
                            3, 3, 3
                          ) ;
begin

   H.G.Init ( Chart ) ;
   H.G.Add  ( Chart, "OP", "#000000", Data_Op ) ;

end smalltest;

I don't know if this is the most elegant and effective way, but it
works.
--
Adrian Hoe
http://adrianhoe.com/adrianhoe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14  6:04       ` Adrian Hoe
@ 2011-06-14  8:01         ` Adrian Hoe
  2011-06-14 16:01           ` Adam Beneschan
  0 siblings, 1 reply; 12+ messages in thread
From: Adrian Hoe @ 2011-06-14  8:01 UTC (permalink / raw)


On Jun 14, 2:04 pm, Adrian Hoe <aby...@gmail.com> wrote:
> On Jun 14, 9:24 am, Adam Beneschan <a...@irvine.com> wrote:
>
>
>
>
>
> > On Jun 13, 6:07 pm, Adrian Hoe <aby...@gmail.com> wrote:
>
> > > I changed the line in procedure Add from
>
> > >       New_Element := new Element_Record'
> > >                         ( Constructor.Init ( Name, Color, Data) ) ;
>
> > > to
>
> > >       New_Element := new Element_Record;
>
> > > The compiler is still pointing the same warning to this line.
>
> > > What exactly does the warning message "Type in allocator has deeper
> > > level than designated class-wide type" mean? Is the compiler unable to
> > > determine the size of the array during allocation? Or the array is a
> > > level deeper than the List.Access_Node?
>
> > It has nothing to do with arrays.  When you declare a type as "access
> > all T'Class", an object of that type can't be made to point to a type
> > declared in a more deeply nested subprogram.  A simple example:
>
> > package Pack1 is
> >     type Root is tagged null record;
> >     type Acc is access all Root'Class;
> > end Pack1;
>
> > package Pack2 is
> >     procedure Proc1;
> > end Pack2;
>
> > with Pack1;
> > package body Pack2 is
> >     procedure Proc1 is
> >         type Child is new Pack1.Root with null record;
> >         A : Pack1.Acc;
> >     begin
> >         A := new Child;   -- ILLEGAL
> >     end Proc1;
> > end Pack2;
>
> > This assignment statement is illegal, because somewhere later, A could
> > be copied to, say, another variable of type Pack1.Acc declared
> > globally in the body of Pack2, and then you'd have a pointer to a
> > Child that would exist after Proc1 has exited and the Child type no
> > longer exists, which is a big no-no.  4.8(5.1) prohibits this.
>
> > Since in this case, the record type (Element_Record) is declared in a
> > generic, that complicates things, because the generic *could* be
> > instantiated inside a procedure, which would lead to the same sort of
> > problem as above.  I don't remember all the rules, but depending on
> > where the type is declared and where the allocator occurs (generic
> > specification or body), it might be illegal to instantiate this
> > generic inside a procedure, or it might cause Program_Error to be
> > raised.  I just tried our compiler again and modified the source to
> > instantiate High_Cloud; if there's an instance of High_Cloud inside a
> > procedure, it *does* give a warning that Program_Error will be raised
> > (if the "new Element_Record" expression is reached).  If your compiler
> > gives the warning when the generic is first seen, before an instance
> > of the generic is seen, that's just a choice your compiler makes.  But
> > unless your program is arranged in a different order than I'm
> > guessing, or unless there are some new Ada 2012 rules that I'm not yet
> > familiar with, the compiler should not reject your generic, and it
> > should not reject it or cause Program_Error to be raised if there's an
> > instance of the generic that is *not* inside a subprogram.
>
> >                                   -- Adam
>
> I see and I followed this post by Robert Duff:https://groups.google.com/group/comp.lang.ada/browse_frm/thread/8fc03...
>
> Hence,
>
> generic
>    type Index is ( <> ) ;
>    type Item is private;
> package High_Cloud is
>
>    package List renames Heterogeneous_Doubly_Link_List;
>    use List;
>
>    type Element_Record           is new List.Node with private;
>    type Series_Access            is new List.Access_List;
> private
>    type Element_Record is new List.Node with
>       record
>          Name           : Unbounded_String;
>          Color          : Unbounded_String;
>          Data           : Item;
>       end record;
> ...
> end High_Cloud;
> In the package body of High_Cloud, I have a procedure:
>    procedure Add
>       ( Cloud          : in out High_Cloud_Record;
>         Name            : in     Unbounded_String;
>         Color           : in     Unbounded_String;
>         Data            : in     Item )
>    is
>       New_Element : List.Access_Node;
>    begin
>       New_Element := new Element_Record'
>                         ( Constructor.Init ( Name, Color, Data) ) ;
>       Concatenate ( Cloud.Series, New_Element ) ;
>    end Add;
>
> To use High_Cloud:
>
> with High_Cloud;
>
> package Hen is
>
>    type I_Array is array ( 1 .. 31 ) of Integer;
>    package G is new High_Cloud ( Positive, I_Array ) ;
>    use G;
>
> end Hen;
>
> and in the procedure, I have:
>
> with High_Cloud;
> with Hen;
>
> procedure smalltest is
>
>    package H renames Hen;
>    use H;
>
>    Data_Op : H.I_Array := ( 3, 4, 2, 3, 3, 3, 0, 3, 6, 3, 2, 6, 8, 7,
>                             3, 4, 3, 5, 1, 3, 1, 2, 2, 0, 2, 6, 8, 7,
>                             3, 3, 3
>                           ) ;
> begin
>
>    H.G.Init ( Chart ) ;
>    H.G.Add  ( Chart, "OP", "#000000", Data_Op ) ;
>
> end smalltest;
>
> I don't know if this is the most elegant and effective way, but it
> works.
> --
> Adrian Hoehttp://adrianhoe.com/adrianhoe


But this defeats my implementation intention which the size and the
type of its data array can only be determined during runtime. Any
suggestion?

Thanks.
--
Adrian Hoe
http://adrianhoe.com/adrianhoe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14  8:01         ` Adrian Hoe
@ 2011-06-14 16:01           ` Adam Beneschan
  2011-06-15  2:04             ` Adrian Hoe
  0 siblings, 1 reply; 12+ messages in thread
From: Adam Beneschan @ 2011-06-14 16:01 UTC (permalink / raw)


On Jun 14, 1:01 am, Adrian Hoe <aby...@gmail.com> wrote:
>
> But this defeats my implementation intention which the size and the
> type of its data array can only be determined during runtime. Any
> suggestion?

There was no reason to change the generic parameters to High_Cloud, or
to change the type of the Data component from Data_Array to Item.  As
I tried to explain, your problem had nothing to do with arrays.  The
problem has to do with where the Element_Record type extension is
declared, which has to do with where the High_Cloud generic is
instantiated.  In your latest example, you instantiated it directly in
a library package, Hen, so there won't be a problem.  If you
instantiate it inside a procedure, there will be a problem.  But the
types of the components don't matter.

If it *does* make a difference---i.e. if declaring Data as a
Data_Array instead of an Item makes things fail, even if High_Cloud is
still instantiated directly inside Hen---then I believe the problem is
with your compiler, and you need to contact your compiler vendor and
file a bug report.

                                  -- Adam




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-14 16:01           ` Adam Beneschan
@ 2011-06-15  2:04             ` Adrian Hoe
  2011-06-15 15:44               ` Adam Beneschan
  0 siblings, 1 reply; 12+ messages in thread
From: Adrian Hoe @ 2011-06-15  2:04 UTC (permalink / raw)


On Jun 15, 12:01 am, Adam Beneschan <a...@irvine.com> wrote:
> On Jun 14, 1:01 am, Adrian Hoe <aby...@gmail.com> wrote:
>
>
>
> > But this defeats my implementation intention which the size and the
> > type of its data array can only be determined during runtime. Any
> > suggestion?
>
> There was no reason to change the generic parameters to High_Cloud, or
> to change the type of the Data component from Data_Array to Item.  As
> I tried to explain, your problem had nothing to do with arrays.  The
> problem has to do with where the Element_Record type extension is
> declared, which has to do with where the High_Cloud generic is
> instantiated.  In your latest example, you instantiated it directly in
> a library package, Hen, so there won't be a problem.  If you
> instantiate it inside a procedure, there will be a problem.  But the
> types of the components don't matter.
>
> If it *does* make a difference---i.e. if declaring Data as a
> Data_Array instead of an Item makes things fail, even if High_Cloud is
> still instantiated directly inside Hen---then I believe the problem is
> with your compiler, and you need to contact your compiler vendor and
> file a bug report.
>
>                                   -- Adam

Yes, of course both methods are working as long as the instantiation
happens at library level. The implementation of I_Array (e.g.
I_Array_31 to indicate array (1..31) of Integer) in Hen gives the
array a name to describe it, rather than Data_Array as in High_Cloud
in the 1st post.

Compiler  error has been ruled out.

Is there any other method other than using "generic" package? Again,
the rule is: The data type and the size of the array can only be
determined during runtime.

Thanks.
--
Adrian Hoe
http://adrianhoe.com/adrianhoe



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Type in allocator has deeper level than designated class-wide type
  2011-06-15  2:04             ` Adrian Hoe
@ 2011-06-15 15:44               ` Adam Beneschan
  0 siblings, 0 replies; 12+ messages in thread
From: Adam Beneschan @ 2011-06-15 15:44 UTC (permalink / raw)


On Jun 14, 7:04 pm, Adrian Hoe <aby...@gmail.com> wrote:
> On Jun 15, 12:01 am, Adam Beneschan <a...@irvine.com> wrote:
>
>
>
>
>
> > On Jun 14, 1:01 am, Adrian Hoe <aby...@gmail.com> wrote:
>
> > > But this defeats my implementation intention which the size and the
> > > type of its data array can only be determined during runtime. Any
> > > suggestion?
>
> > There was no reason to change the generic parameters to High_Cloud, or
> > to change the type of the Data component from Data_Array to Item.  As
> > I tried to explain, your problem had nothing to do with arrays.  The
> > problem has to do with where the Element_Record type extension is
> > declared, which has to do with where the High_Cloud generic is
> > instantiated.  In your latest example, you instantiated it directly in
> > a library package, Hen, so there won't be a problem.  If you
> > instantiate it inside a procedure, there will be a problem.  But the
> > types of the components don't matter.
>
> > If it *does* make a difference---i.e. if declaring Data as a
> > Data_Array instead of an Item makes things fail, even if High_Cloud is
> > still instantiated directly inside Hen---then I believe the problem is
> > with your compiler, and you need to contact your compiler vendor and
> > file a bug report.
>
> >                                   -- Adam
>
> Yes, of course both methods are working as long as the instantiation
> happens at library level. The implementation of I_Array (e.g.
> I_Array_31 to indicate array (1..31) of Integer) in Hen gives the
> array a name to describe it, rather than Data_Array as in High_Cloud
> in the 1st post.
>
> Compiler  error has been ruled out.
>
> Is there any other method other than using "generic" package? Again,
> the rule is: The data type and the size of the array can only be
> determined during runtime.

OK, I wasn't really clear on your requirements.  (Mostly I was trying
to solve your legality issue.)

If just the size had to be determined during runtime, I'd suggest
using a discriminant record with the size as the discriminant; you
could define "Data" as an array whose bound depends on that
discriminant (and get rid of the generic formal parameter N).  More
specifically:

   type Data_Array is array (Positive range <>) of Item;

   type Element_Record (N : Positive) is new List.Node with
       record
          Name : Unbounded_String;
          Color : Unbounded_String;
          Data  : Data_Array (1 .. N);
       end record;

But I'm not sure what you mean by "the data type is determined at
runtime".  In the solution you're trying to use, you instantiate
High_Cloud with the upper bound and an Item type, and apparently
you're instantiating it inside a procedure.  But although the upper
bound "N" may be something you have to compute inside the procedure,
in most cases the Item type should be something that can be defined
outside the procedure.  In one of you examples, you seemed to use
Integer for the Item type.  This means that if you get rid of the
generic formal parameter N and make it a record discriminant, as I
explained above, you can then instantiate High_Cloud with Item =>
Integer *outside* the procedure, and then you can still have an
Element_Record whose size depends on values you define inside the
procedure, but since the type is actually defined outside the
procedure, you won't have the access type violation problems.  (Note:
I have not tried this.  I think it will work.)

Hopefully that should be enough to solve your problem.  But if you
still think that the "data type" has to be defined inside the
procedure, you'll need to give an example that demonstrates why.  Ada
doesn't really have the ability to construct new types at runtime.

                                 -- Adam




^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-06-15 15:44 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-13 15:31 Type in allocator has deeper level than designated class-wide type Adrian Hoe
2011-06-13 17:11 ` Adam Beneschan
2011-06-14  0:49   ` Adrian Hoe
2011-06-14  1:08     ` Adam Beneschan
2011-06-14  1:11       ` Adrian Hoe
2011-06-14  1:07   ` Adrian Hoe
2011-06-14  1:24     ` Adam Beneschan
2011-06-14  6:04       ` Adrian Hoe
2011-06-14  8:01         ` Adrian Hoe
2011-06-14 16:01           ` Adam Beneschan
2011-06-15  2:04             ` Adrian Hoe
2011-06-15 15:44               ` Adam Beneschan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox