From: Adrian Hoe <abyhoe@gmail.com>
Subject: Re: Type in allocator has deeper level than designated class-wide type
Date: Tue, 14 Jun 2011 01:01:13 -0700 (PDT)
Date: 2011-06-14T01:01:13-07:00 [thread overview]
Message-ID: <b6ec6c67-dce6-408c-8885-f55b4263bf88@v11g2000prk.googlegroups.com> (raw)
In-Reply-To: b71e580e-0715-439b-9f20-33e0c6db8b16@r27g2000prr.googlegroups.com
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
next prev parent reply other threads:[~2011-06-14 8:01 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2011-06-14 16:01 ` Adam Beneschan
2011-06-15 2:04 ` Adrian Hoe
2011-06-15 15:44 ` Adam Beneschan
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox