comp.lang.ada
 help / color / mirror / Atom feed
* Size of a pointer to a tagged record
@ 2002-12-04 14:01 Steven Murdoch
  2002-12-04 15:16 ` Robert A Duff
  2002-12-04 17:05 ` Jeffrey Carter
  0 siblings, 2 replies; 10+ messages in thread
From: Steven Murdoch @ 2002-12-04 14:01 UTC (permalink / raw)


I am writing a binding to the Lua (http://www.lua.org/)
scripting language (which is written in C). One thing I
need to do is store a pointer to a tagged record in a
memory location allocated by malloc. For this reason I need
to know the size.

If a pointer to a tagged record is equivalent to a
System.Address then I can store this in a memory location
of sizeof(void *), however if the tag is stored in the
pointer rather than the record then I would need to
allocate space for the tag as well.

If a pointer to a tagged record is equivalent to a
System.Address then I would use the following code:

--

type Parameter is tagged private;
type Parameter_Access is access all Parameter'Class;

package Convert is new
     System.Address_To_Access_Conversions(Parameter);

addr: System.Address;
param: Parameter_Access;

addr:=Get_Void_Pointer; --Void* from C
param:=Parameter_Access(User_Data_Convert.To_Pointer(Address));

--

At the end of this code I would use param as a normal pointer
to a tagged record. Does this look OK? Is there a better way
to achieve the same thing.

I am using GNAT 3.13p but I would like the code to be as
cross platform/compiler as possible.

Thanks in advance,
Steven Murdoch.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 14:01 Size of a pointer to a tagged record Steven Murdoch
@ 2002-12-04 15:16 ` Robert A Duff
  2002-12-04 15:44   ` Steven Murdoch
  2002-12-04 17:05 ` Jeffrey Carter
  1 sibling, 1 reply; 10+ messages in thread
From: Robert A Duff @ 2002-12-04 15:16 UTC (permalink / raw)


news01+Steven.Murdoch@cl.cam.ac.uk (Steven Murdoch) writes:

> I am writing a binding to the Lua (http://www.lua.org/)
> scripting language (which is written in C). One thing I
> need to do is store a pointer to a tagged record in a
> memory location allocated by malloc. For this reason I need
> to know the size.
> 
> If a pointer to a tagged record is equivalent to a
> System.Address then I can store this in a memory location
> of sizeof(void *), however if the tag is stored in the
> pointer rather than the record then I would need to
> allocate space for the tag as well.
> 
> If a pointer to a tagged record is equivalent to a
> System.Address then I would use the following code:

All the Ada compilers I am familiar with represent access-to-tagged as a
single address.  The tag is stored in the tagged record, not in the
pointer.

I don't think it's even feasible to store the tag with the pointer,
because of a last-minute change to Ada 95 -- all tagged parameters are
aliased.

However, I don't understand what you're trying to do.  How can C code
produce a pointer to a tagged type?  I mean, the tag has to be
initialized on the Ada side.  And why must the *pointer* be heap
allocated?

If the tag *were* stored in the pointer, then you would not only have to
allocate space for it, but somehow set it to the right value.

> --
> 
> type Parameter is tagged private;
> type Parameter_Access is access all Parameter'Class;
> 
> package Convert is new
>      System.Address_To_Access_Conversions(Parameter);
> 
> addr: System.Address;
> param: Parameter_Access;
> 
> addr:=Get_Void_Pointer; --Void* from C
> param:=Parameter_Access(User_Data_Convert.To_Pointer(Address));
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
That code is wrong, so I'm not sure what you mean.

I presume Get_Void_Pointer is pragma Import(C).  And it does a "malloc",
passing sizeof(void *).  So it's returning a pointer to a pointer.  Is
that right?

Anyway, why not declare Get_Void_Pointer to return the access type?
I see no need for Address_To_Access_Conversions.

> At the end of this code I would use param as a normal pointer
> to a tagged record. Does this look OK? Is there a better way
> to achieve the same thing.
> 
> I am using GNAT 3.13p but I would like the code to be as
> cross platform/compiler as possible.

You can find out the size of a pointer by writing a little test program
that prints out Parmeter_Access'Size, and running it on as many Ada
compilers as you can get your hands on.

- Bob



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 15:16 ` Robert A Duff
@ 2002-12-04 15:44   ` Steven Murdoch
  2002-12-04 17:17     ` Robert A Duff
  2002-12-04 18:11     ` tmoran
  0 siblings, 2 replies; 10+ messages in thread
From: Steven Murdoch @ 2002-12-04 15:44 UTC (permalink / raw)


Thanks for your reply.

In article <wcc3cpd3jd7.fsf@shell01.TheWorld.com>,
 you write:
>All the Ada compilers I am familiar with represent access-to-tagged as a
>single address.  The tag is stored in the tagged record, not in the
>pointer.

OK, that is what I hoped.

>However, I don't understand what you're trying to do.  How can C code
>produce a pointer to a tagged type?  I mean, the tag has to be
>initialized on the Ada side.  And why must the *pointer* be heap
>allocated?

The tagged record and pointer are created by a Ada "new" statement
the the pointer is passed to the Lua API and stored by it.
In order to store things in Lua you give it the contents of the object
and size (in bytes). This is effectively passed to malloc and the space
for the pointer is allocated (plus some Lua internals).

Control then passes to Lua and at some point it will ask the Ada
program to perform some action on the data so will pass the data
back to Ada, which is the same as the contents passed in
earlier, i.e. a pointer to a tagged record. 

>If the tag *were* stored in the pointer, then you would not only have to
>allocate space for it, but somehow set it to the right value.

Ada would handle setting the tag, the C part just takes a value 
and stores it, it eventually returns it.

>
>> --
>> 
>> type Parameter is tagged private;
>> type Parameter_Access is access all Parameter'Class;
>> 
>> package Convert is new
>>      System.Address_To_Access_Conversions(Parameter);
>> 
>> addr: System.Address;
>> param: Parameter_Access;
>> 
>> addr:=Get_Void_Pointer; --Void* from C
>> param:=Parameter_Access(User_Data_Convert.To_Pointer(Address));
>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>That code is wrong, so I'm not sure what you mean.

Well it compiles.

>I presume Get_Void_Pointer is pragma Import(C).  And it does a "malloc",
>passing sizeof(void *).

Get_Void_Pointer doesn't do a malloc, it returns a pointer
to a tagged record, which was stored somewhere in the heap.

At a previous point a malloc was done to create a memory location X,
in which was stored the address of a tagged record. The address of
X is hidden by Lua, but it's contents are passed back to Ada by
Get_Void_Pointer.

> So it's returning a pointer to a pointer.  Is
> that right?

No, just a pointer to a tagged record.

>Anyway, why not declare Get_Void_Pointer to return the access type?
>I see no need for Address_To_Access_Conversions.

What would it's type in C be in that case? Currently is returns
a "void *" which I believe is equivalent to a System.Address. What
would it's type be if it it returned an "Parameter_Access"?
Is it safe to mark a pragma Import(C) function as returning a
Parameter_Access? Would this be a better idea?

>You can find out the size of a pointer by writing a little test program
>that prints out Parmeter_Access'Size, and running it on as many Ada
>compilers as you can get your hands on.

On GNAT 3.13p it is 32 (I assume bytes) which is indeed the same
size as System.Address.

Thank you,
Steven Murdoch.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 14:01 Size of a pointer to a tagged record Steven Murdoch
  2002-12-04 15:16 ` Robert A Duff
@ 2002-12-04 17:05 ` Jeffrey Carter
  1 sibling, 0 replies; 10+ messages in thread
From: Jeffrey Carter @ 2002-12-04 17:05 UTC (permalink / raw)


Steven Murdoch wrote:
> I am writing a binding to the Lua (http://www.lua.org/)
> scripting language (which is written in C). One thing I
> need to do is store a pointer to a tagged record in a
> memory location allocated by malloc. For this reason I need
> to know the size.

If you declare your access type as having Convention C, then it will be 
the same size as a C pointer, and your C stuff can safely use the size 
of a C pointer.

If you tell the C side what size to use, then why not simply calculate 
the size to pass to C? You can use 
Type_Name'Max_Size_In_Storage_Elements, or {Object_Name'Size + 
Storage_Unit - 1) / Storage_Unit.

-- 
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 15:44   ` Steven Murdoch
@ 2002-12-04 17:17     ` Robert A Duff
  2002-12-04 17:56       ` Steven Murdoch
  2002-12-04 20:27       ` Simon Wright
  2002-12-04 18:11     ` tmoran
  1 sibling, 2 replies; 10+ messages in thread
From: Robert A Duff @ 2002-12-04 17:17 UTC (permalink / raw)


news01+Steven.Murdoch@cl.cam.ac.uk (Steven Murdoch) writes:

> Thanks for your reply.

You're welcome.

> >> type Parameter is tagged private;
> >> type Parameter_Access is access all Parameter'Class;
> >> 
> >> package Convert is new
> >>      System.Address_To_Access_Conversions(Parameter);
> >> 
> >> addr: System.Address;
> >> param: Parameter_Access;
> >> 
> >> addr:=Get_Void_Pointer; --Void* from C
> >> param:=Parameter_Access(User_Data_Convert.To_Pointer(Address));
> >         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >That code is wrong, so I'm not sure what you mean.
> 
> Well it compiles.

I see nothing called User_Data_Convert in the above code.
Perhaps you meant Convert?

Also, the result of To_Pointer is Parameter_Access,
so you don't need to additionally convert to Parameter_Access
(by saying "Parameter_Access(...)").  That would compile,
but it's silly to convert from a type to itself.

If you want to clarify the type (just to make the code more readable),
use a qualified expression, as in "Parameter_Access'(...)".
                                                   ^
                                                   ^

> >Anyway, why not declare Get_Void_Pointer to return the access type?
> >I see no need for Address_To_Access_Conversions.
> 
> What would it's type in C be in that case?

void *

>... Currently is returns
> a "void *" which I believe is equivalent to a System.Address. What
> would it's type be if it it returned an "Parameter_Access"?
> Is it safe to mark a pragma Import(C) function as returning a
> Parameter_Access?

No, it's not safe.  But interfacing across languages is never safe --
you always have to make sure the sizes of things match.

> ...Would this be a better idea?

I have no opinion either way.

> >You can find out the size of a pointer by writing a little test program
> >that prints out Parmeter_Access'Size, and running it on as many Ada
> >compilers as you can get your hands on.
> 
> On GNAT 3.13p it is 32 (I assume bytes) which is indeed the same
> size as System.Address.

'Size is in bits, not bytes.

One thing you might think about is taking 'Size on the Ada side,
converting that to bytes (using System.Storage_Unit), and passing
that to the C code at some point.  The C code might be able to
use that size, or else assert that it is correct.

- Bob



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 17:17     ` Robert A Duff
@ 2002-12-04 17:56       ` Steven Murdoch
  2002-12-04 19:10         ` Robert A Duff
  2002-12-07  6:55         ` David Thompson
  2002-12-04 20:27       ` Simon Wright
  1 sibling, 2 replies; 10+ messages in thread
From: Steven Murdoch @ 2002-12-04 17:56 UTC (permalink / raw)


In article <wccvg29d7q8.fsf@shell01.TheWorld.com>,
 Robert A Duff <bobduff@shell01.TheWorld.com> writes:

>> >> addr:=Get_Void_Pointer; --Void* from C
>> >> param:=Parameter_Access(User_Data_Convert.To_Pointer(Address));
>> >         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> >That code is wrong, so I'm not sure what you mean.
>> 
>> Well it compiles.
>
>I see nothing called User_Data_Convert in the above code.
>Perhaps you meant Convert?

Yes, sorry (I forgot to simplify that when I pasted it in)

>Also, the result of To_Pointer is Parameter_Access,
>so you don't need to additionally convert to Parameter_Access
>(by saying "Parameter_Access(...)").  That would compile,
>but it's silly to convert from a type to itself.

If I take out the "Parameter_Access(...)" I get the following error message:
lua.adb:172:35: expected type "Parameter_Access" defined at lua.ads:13
lua.adb:172:35: found type "System.Address_To_Access_Conversions.Object_Pointer" from instance at line 36
so it seems that the result of To_Pointer is Object_Pointer rather than Parameter_Access.

>> >Anyway, why not declare Get_Void_Pointer to return the access type?
>> >I see no need for Address_To_Access_Conversions.
>> 
>> What would it's type in C be in that case?
>
>void *

OK, I will try that, it would clean up my code substantially.

>> On GNAT 3.13p it is 32 (I assume bytes) which is indeed the same
>> size as System.Address.
>
>'Size is in bits, not bytes.

Sorry, that's what I meant. 32 byte addresses would be a rather larger
address space that would be necessary :-)

>One thing you might think about is taking 'Size on the Ada side,
>converting that to bytes (using System.Storage_Unit), and passing
>that to the C code at some point.  The C code might be able to
>use that size, or else assert that it is correct.

I will try that too, the size is set during run time so there
should not be any problem setting it. IIRC Malloc takes a number of
octets so I could use a variant of Jeff Carters suggestion such as
(Parameter_Access'Size + 7) / 8
This should be the right thing to pass in, even if Storage_Unit is not 8

Thanks again,
Steven Murdoch.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 15:44   ` Steven Murdoch
  2002-12-04 17:17     ` Robert A Duff
@ 2002-12-04 18:11     ` tmoran
  1 sibling, 0 replies; 10+ messages in thread
From: tmoran @ 2002-12-04 18:11 UTC (permalink / raw)


> Ada would handle setting the tag, the C part just takes a value
> and stores it, it eventually returns it.
  If the C part just sees a set of bits and doesn't care what it
represents, then the fact it's an access to a tagged type is irrelevant,
it could just as well be an integer or string or whatever.  You just
need, on the Ada side, to use attributes to find the size of the
black box object you are sending to C.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 17:56       ` Steven Murdoch
@ 2002-12-04 19:10         ` Robert A Duff
  2002-12-07  6:55         ` David Thompson
  1 sibling, 0 replies; 10+ messages in thread
From: Robert A Duff @ 2002-12-04 19:10 UTC (permalink / raw)


news01+Steven.Murdoch@cl.cam.ac.uk (Steven Murdoch) writes:

> If I take out the "Parameter_Access(...)" I get the following error message:
> lua.adb:172:35: expected type "Parameter_Access" defined at lua.ads:13
> lua.adb:172:35: found type "System.Address_To_Access_Conversions.Object_Pointer" from instance at line 36
> so it seems that the result of To_Pointer is Object_Pointer rather than Parameter_Access.

Oh yeah, you're right.  I had forgotten how A_T_A_C works.
Sorry about that.

> Sorry, that's what I meant. 32 byte addresses would be a rather larger
> address space that would be necessary :-)

;-)

- Bob



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 17:17     ` Robert A Duff
  2002-12-04 17:56       ` Steven Murdoch
@ 2002-12-04 20:27       ` Simon Wright
  1 sibling, 0 replies; 10+ messages in thread
From: Simon Wright @ 2002-12-04 20:27 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> One thing you might think about is taking 'Size on the Ada side,
> converting that to bytes (using System.Storage_Unit), and passing
> that to the C code at some point.  The C code might be able to
> use that size, or else assert that it is correct.

Would 'Max_Size_In_Storage_Elements be relevant here?



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Size of a pointer to a tagged record
  2002-12-04 17:56       ` Steven Murdoch
  2002-12-04 19:10         ` Robert A Duff
@ 2002-12-07  6:55         ` David Thompson
  1 sibling, 0 replies; 10+ messages in thread
From: David Thompson @ 2002-12-07  6:55 UTC (permalink / raw)


Steven Murdoch <news01+Steven.Murdoch@cl.cam.ac.uk> wrote :
> In article <wccvg29d7q8.fsf@shell01.TheWorld.com>,
>  Robert A Duff <bobduff@shell01.TheWorld.com> writes:
...
> >One thing you might think about is taking 'Size on the Ada side,
> >converting that to bytes (using System.Storage_Unit), and passing
> >that to the C code at some point.  The C code might be able to
> >use that size, or else assert that it is correct.
>
> I will try that too, the size is set during run time so there
> should not be any problem setting it. IIRC Malloc takes a number of
> octets so I could use a variant of Jeff Carters suggestion such as
> (Parameter_Access'Size + 7) / 8
> This should be the right thing to pass in, even if Storage_Unit is not 8
>
C malloc et al measure size in bytes as defined by that
C implementation, which must be at least 8 bits but may
be more, for exactly the same reasons SSU may vary;
the value is provided by macro CHAR_BIT in <limits.h>.

Neither standard requires C CHAR_BIT to equal Ada SSU,
it would be out of scope;  but logically they should be the same,
and if your implementation doesn't do so I think you're out of luck.

--
- David.Thompson 1 now at worldnet.att.net






^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-12-07  6:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-04 14:01 Size of a pointer to a tagged record Steven Murdoch
2002-12-04 15:16 ` Robert A Duff
2002-12-04 15:44   ` Steven Murdoch
2002-12-04 17:17     ` Robert A Duff
2002-12-04 17:56       ` Steven Murdoch
2002-12-04 19:10         ` Robert A Duff
2002-12-07  6:55         ` David Thompson
2002-12-04 20:27       ` Simon Wright
2002-12-04 18:11     ` tmoran
2002-12-04 17:05 ` Jeffrey Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox