|
Prev: To collection (GNAT bug)
Next: Ada compiler
From: cl1 on 30 Sep 2006 17:20 I don't understand why i can't pass Av_Param to the generic package (in test_call_avcall_register_type.adb) and have its 'Access attribute used in Concat (the offending code in avcall-register_type.adb)? i'm getting the following error: $ gnatmake -gnatc ./Ada_Source/test_avcall_register_type.adb gcc -c -I./Ada_Source/ -gnatc -I- ../Ada_Source/test_avcall_register_type.adb gcc -c -I./Ada_Source/ -gnatc -I- ./Ada_Source/avcall.adb gcc -c -I./Ada_Source/ -gnatc -I- ./Ada_Source/avcall-register_type.adb avcall-register_type.adb:13:34: not subtype conformant with declaration at avcall.ads:37 avcall-register_type.adb:13:34: formal subprograms not allowed gnatmake: "./Ada_Source/avcall-register_type.adb" compilation error on this code: <avcall.ads> with System; use System; package avcall is -- <snip> ---------------------------------------------------------------------------- -- This exeption is thrown when you try to add more than Max_Args to the -- Var_Args type Max_Arg_Limit_Surpassed : exception; ---------------------------------------------------------------------------- -- The maximum number of arguments that can be used by avcall Max_Args : constant := 50; ---------------------------------------------------------------------------- -- this is the number of arguments in the Var_Args list subtype Arg_Count is Natural range 0..Max_Args; ---------------------------------------------------------------------------- -- This is the range used by the Var_Args list subtype Arg_Range is Natural range 1..Max_Args; ---------------------------------------------------------------------------- -- this represents an argument held in the Arg_List type Argument is tagged record ------------------------------------------------------------------------ -- This holds the correct av_<type> c function to call. Av_Param : access procedure(Av_List : System.Address; Value : System.Address); ------------------------------------------------------------------------ -- This holds the address of the value. This is assigned by the child -- type of this type in the Register_Type package during the -- Initialize procedure call of the child type. Value_Address : System.Address; ------------------------------------------------------------------------ end record; ---------------------------------------------------------------------------- -- This type is used by the Var_Args type to hold all of the arguments. type Arg_List is array(Arg_Range range <>) of Argument; ---------------------------------------------------------------------------- -- This is the Var_Args type. This is used to hold all of the arguments to -- the c function (the ... and all the arguments before that). -- The Start_Var_Args, "&", and Prepend methods and functions are used to -- add arguments to Var_Args. type Var_Args is record ------------------------------------------------------------------------ -- this is a pointer to the c data type that makes this work. -- Av_List_Malloc and Av_List_Free (defined in the body) are used to -- obtain the reference and free it respectivly Av_List : System.Address; ------------------------------------------------------------------------ -- This is the number of arguments in the Arg_List Count : access Arg_Count; ------------------------------------------------------------------------ -- This is what holds all of the arguments. List : access Arg_List := new Arg_List(Arg_Range'Range); ------------------------------------------------------------------------ end record; ---------------------------------------------------------------------------- -- <snip> end avcall; <avcall-register_type.ads> with System.Address_To_Access_Conversions; with System; use System; -------------------------------------------------------------------------------- generic type Any_Type is private; with procedure Av_Param_Instance(AList : System.Address; Value : System.Address); package avcall.register_type is ---------------------------------------------------------------------------- package Any_Type_Conversion is new System.Address_To_Access_Conversions(Any_Type); ---------------------------------------------------------------------------- type Argument_Instance is new Argument with record Instance_Value : Any_Type_Conversion.Object_Pointer; end record; ---------------------------------------------------------------------------- function Concat(AList : Var_Args; Arg : Any_Type) return Var_Args; ---------------------------------------------------------------------------- end avcall.register_type; <avcall-register_type.adb> package body avcall.register_type is ---------------------------------------------------------------------------- -- Adds the value in Arg to the next Var_Args.List function Concat(AList : Var_Args; Arg : Any_Type) return Var_Args is Info : Argument_Instance; begin Info.Av_Param := Av_Param_Instance'Access; Info.Instance_Value.all := Arg; Info.Value_Address := Any_Type_Conversion.To_Address(Info.Instance_Value); AList.Count.all := AList.Count.all + 1; AList.List(AList.Count.all) := Argument(Info); return AList; end Concat; ---------------------------------------------------------------------------- end avcall.register_type; <test_avcall_register_type.adb> with avcall; use avcall; with avcall.register_type; with Ada.Text_IO; use Ada.Text_IO; with System; use System; -------------------------------------------------------------------------------- procedure test_avcall_register_type is procedure Av_Param(AList : System.Address; Value : System.Address) is begin null; end Av_Param; package Int_Registered is new avcall.register_type(Integer, Av_Param); begin Put_Line("FOO"); end test_avcall_register_type; <offending code> --avcall-register_type.adb:13:34: not subtype conformant with declaration at avcall.ads:37 --avcall-register_type.adb:13:34: formal subprograms not allowed Info.Av_Param := Av_Param_Instance'Access; <end of code post> I don't understand why i can't pass Av_Param to the generic package (in test_call_avcall_register_type.adb) and have its 'Access attribute used in Concat (the offending code in avcall-register_type.adb)?
From: cl1 on 1 Oct 2006 02:02 Jeffrey R. Carter wrote: > cl1 wrote: > > --avcall-register_type.adb:13:34: not subtype conformant with > > declaration at avcall.ads:37 > > --avcall-register_type.adb:13:34: formal subprograms not allowed > > Info.Av_Param := Av_Param_Instance'Access; > > <end of code post> > > You seem to have cut things down a bit too much. avcall.ads has no line > 37. If you're going to cut things down this much, please post messages > that result from compiling the cut-down code. that is why i posted the very last section called <offending code> so you could see which line it was. I didn't think to compile the cut down code. I appologize. line 37 is lines 23 and 24 in the snippet of avcall.ads > > You shouldn't use System.Address to interface to C. Use a convention-C > access type instead. I understand the reason for using access types with convention C, but that will not work for this situation. Everywhere i have used System.Address the code does not know, does not care what type or subprogram signature is stored there, and will not use it other than to pass it along to some c function that knows what to do with it. If there is a System.Address being used that doesn't fit that, then it is a bug. I also choose not to use 'type void_ptr is new System.Address;' specifically becuase that is what System.Address is. Also someone once told me that writing code that requires the user to with System; alerts the user that the code is system dependant. I like that idea. This code is system dependant. By that, I mean it is dependant on the processor and in some situations the operating system, not the compiler implementation. Well to be honest the Ada code isn't but the C code it interfaces with is (ffcall's avcall). > > > I don't understand why i can't pass Av_Param to the generic package (in > > test_call_avcall_register_type.adb) and have its 'Access attribute used > > in Concat (the offending code in avcall-register_type.adb)? > > You don't say what version of GNAT you're using. i'm using GPS which has gcc version 3.4.6 on mac os x 10.4.8 > However, I suspect what > you're running into is an accessibility control problem. You can't store > the generic formal procedure's 'access because the compiler can't be > sure that the life of the access value is no longer than the life of the > actual procedure. I agree with you. However, I am confused about this. The procedure could be declared anywhere. How does the compiler know what scope the procedure that is supplied to the generic package is in? I mean can it ever know? If not, that means there is no foreseeable fix to this issue from my point of view. > > -- > Jeff Carter > "Sir Lancelot saves Sir Gallahad from almost certain temptation." > Monty Python & the Holy Grail > 69
From: Simon Wright on 1 Oct 2006 03:18 Put this somewhere (in package avcall I guess) type Av_Param_Access is access procedure (AList : System.Address; Value : System.Address); then generic type Any_Type is private; Av_Param_Instance : Av_Param_Access; package avcall.register_type is Compiles OK (same environment as you), whether it is correct and whether it works are of course different matters.
From: cl1 on 1 Oct 2006 15:42 Simon Wright wrote: > Put this somewhere (in package avcall I guess) > > type Av_Param_Access > is access procedure (AList : System.Address; > Value : System.Address); > > then > > generic > type Any_Type is private; > Av_Param_Instance : Av_Param_Access; > package avcall.register_type is > > Compiles OK (same environment as you), whether it is correct and > whether it works are of course different matters. Thank you very much. It fixed the problem, but i do not understand why: with procedure Av_Param_Instance(Av_List, Value : System.Address); does not work. If anyone knows why, I would be greatfull for an explination.
From: Robert A Duff on 1 Oct 2006 16:18
"cl1" <charles.w.lambert(a)gmail.com> writes: > Thank you very much. > It fixed the problem, but i do not understand why: > with procedure Av_Param_Instance(Av_List, Value : System.Address); > does not work. If anyone knows why, I would be greatfull for an > explination. And you wanted to do Av_Param_Instance'Access inside the generic? That won't work, because the compiler can't check the rules about X'Access, because it doesn't know enough about the actual parameter passed to Av_Param_Instance. The accessibility rules come to mind. Also, the fact that you can't do X'Access if X is intrinsic. - Bob |