From: Adrian Hoe <abyhoe@gmail.com>
Subject: Re: Type in allocator has deeper level than designated class-wide type
Date: Mon, 13 Jun 2011 23:04:01 -0700 (PDT)
Date: 2011-06-13T23:04:01-07:00 [thread overview]
Message-ID: <b71e580e-0715-439b-9f20-33e0c6db8b16@r27g2000prr.googlegroups.com> (raw)
In-Reply-To: e507e82a-c8e8-4608-b033-fea6fe93839b@d26g2000prn.googlegroups.com
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
next prev parent reply other threads:[~2011-06-14 6:04 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 [this message]
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
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox