From: cl1 on
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
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
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
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
"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
 |  Next  |  Last
Pages: 1 2 3
Prev: To collection (GNAT bug)
Next: Ada compiler