* 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-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-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 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