Jump to page: 1 2
Thread overview
determining if a void* points to a valid Object
Aug 17, 2006
Luís Marques
Aug 17, 2006
Sean Kelly
Aug 17, 2006
Luís Marques
Aug 17, 2006
BCS
Aug 17, 2006
Luís Marques
Aug 17, 2006
BCS
Aug 17, 2006
Luís Marques
Aug 19, 2006
BCS
Aug 17, 2006
nobody
Aug 17, 2006
Luís Marques
Aug 17, 2006
nobody
Aug 17, 2006
xs0
Aug 18, 2006
Luís Marques
August 17, 2006
Hello all,

I'm making a transition of a code base from C to D. I wish to alleviate the transition by making it gradual, but that requires being able to distinguish D Objects from the existing C structs, given a pointer.

Could you help me with this please?

1. You have a "void *ptr".
2. You have a struct NotDObject whose declaration you can control. (e.g. add fields and require that they possess certain values)

How do you determine with fairly good reliability if ptr points to an Object or to a NotDObject struct?

You are allowed to assume that DMD/GDC is used, and even a specific version of that compiler. I don't care much if it is a kludge (it's a temporary solution), but extra points if you can make it implementation independent.

Thanks a lot,
Luís Marques
August 17, 2006
Luís Marques wrote:
> Hello all,
> 
> I'm making a transition of a code base from C to D. I wish to alleviate the transition by making it gradual, but that requires being able to distinguish D Objects from the existing C structs, given a pointer.
> 
> Could you help me with this please?
> 
> 1. You have a "void *ptr".
> 2. You have a struct NotDObject whose declaration you can control. (e.g. add fields and require that they possess certain values)
> 
> How do you determine with fairly good reliability if ptr points to an Object or to a NotDObject struct?

It would be a horrible hack, but you might be able to test whether the location reserved for the vtbl ptr points to a location where vtbls are known to reside.  The ABI might be of help here: http://www.digitalmars.com/d/abi.html  You will have to ask Walter or do some sleuthing to sort out how to determine this address range, however.


Sean
August 17, 2006
Sean Kelly wrote:
> It would be a horrible hack, but you might be able to test whether the location reserved for the vtbl ptr points to a location where vtbls are known to reside.  The ABI might be of help here: http://www.digitalmars.com/d/abi.html  You will have to ask Walter or do some sleuthing to sort out how to determine this address range, however.

http://www.digitalmars.com/d/abi.html tells us:

An object consists of:

offset 	contents
0       pointer to vtable
4       monitor
8... 	non-static members

So if the NotDObject struct was defined as { void *isobject = null; ... } then we could look at isobject and if was not null it would be a D Object. Or can a D Object not have a vtable? That is, could the "pointer to vtable" be null? Even if that was the case I could add dummy virtual methods to my classes...

Btw: I guess this ABI is 32 bit only :/

Thanks Sean!

Luís
August 17, 2006
Luís Marques wrote:
> Hello all,
> 
> I'm making a transition of a code base from C to D. I wish to alleviate the transition by making it gradual, but that requires being able to distinguish D Objects from the existing C structs, given a pointer.
> 
> Could you help me with this please?
> 
> 1. You have a "void *ptr".
> 2. You have a struct NotDObject whose declaration you can control. (e.g. add fields and require that they possess certain values)
> 
> How do you determine with fairly good reliability if ptr points to an Object or to a NotDObject struct?
> 
> You are allowed to assume that DMD/GDC is used, and even a specific version of that compiler. I don't care much if it is a kludge (it's a temporary solution), but extra points if you can make it implementation independent.
> 
> Thanks a lot,
> Luís Marques

void* ptr;
// set ptr;
if(null !is cast(Object)ptr)
{
	// ptr is an object
}

This should work because type checking is done on object up cast.

However it dosn't seem to work.

Maybe this is a bug.
August 17, 2006
Luís Marques wrote:
> Hello all,
> 
> I'm making a transition of a code base from C to D. I wish to alleviate the transition by making it gradual, but that requires being able to distinguish D Objects from the existing C structs, given a pointer.
> 
> Could you help me with this please?
> 
> 1. You have a "void *ptr".
> 2. You have a struct NotDObject whose declaration you can control. (e.g. add fields and require that they possess certain values)
> 
> How do you determine with fairly good reliability if ptr points to an Object or to a NotDObject struct?
> 
> You are allowed to assume that DMD/GDC is used, and even a specific version of that compiler. I don't care much if it is a kludge (it's a temporary solution), but extra points if you can make it implementation independent.
> 
> Thanks a lot,
> Luís Marques

D Application Binary Interface
http://digitalmars.com/d/class.html

Classes
An object consists of:

offset 	contents
0 	pointer to vtable
4 	monitor
8... 	non-static members


I think if I understand your question correctly then I believe what you can do if first assert( ptr !is null ). Now if I can define NotDObject and initialize the members I would do the following:


  struct NotDObject
  {
    int reserveredA = 0;
    int reserveredB = 0;
    // anything you want follows here
  }

Now since we know ptr is not null then it it points to a NotDObject then dereferencing the pointer should give us a null value. Otherwise we now have a pointer to the vtable from the D ABI above.

  if((*(cast(void*)) is null ) // NotDObject
  else                         // Object
August 17, 2006
BCS wrote:
> void* ptr;
> // set ptr;
> if(null !is cast(Object)ptr)
> {
>     // ptr is an object
> }
> 
> This should work because type checking is done on object up cast.
> 
> However it dosn't seem to work.

According to my experience, from void* to any type it always works. Only from Object to subclasses (or among other types, I guess) it actually does type checking. So if you want to force a cast to another incompatible classe you can do "cast(OtherClass)cast(void*)".

Luís
August 17, 2006
nobody wrote:
> I think if I understand your question correctly then I believe what you can do if first assert( ptr !is null ). Now if I can define NotDObject and initialize the members I would do the following:
> 
> 
>   struct NotDObject
>   {
>     int reserveredA = 0;
>     int reserveredB = 0;
>     // anything you want follows here
>   }
> 
> Now since we know ptr is not null then it it points to a NotDObject then dereferencing the pointer should give us a null value. Otherwise we now have a pointer to the vtable from the D ABI above.
> 
>   if((*(cast(void*)) is null ) // NotDObject
>   else                         // Object

Yes, that's exactly what I need (thanks).

But 1) I guess reserveredB is unnecessary, no? 2) see my previous question: 'can a D Object not have a vtable? That is, could the "pointer to vtable" be null?' (what happens? it points to a 0 entry table?)

Luís
August 17, 2006
Luís Marques wrote:
> nobody wrote:
>> I think if I understand your question correctly then I believe what you can do if first assert( ptr !is null ). Now if I can define NotDObject and initialize the members I would do the following:
>>
>>
>>   struct NotDObject
>>   {
>>     int reserveredA = 0;
>>     int reserveredB = 0;
>>     // anything you want follows here
>>   }
>>
>> Now since we know ptr is not null then it it points to a NotDObject then dereferencing the pointer should give us a null value. Otherwise we now have a pointer to the vtable from the D ABI above.
>>
>>   if((*(cast(void*)) is null ) // NotDObject
>>   else                         // Object
> 
> Yes, that's exactly what I need (thanks).
> 
> But 1) I guess reserveredB is unnecessary, no? 2) see my previous question: 'can a D Object not have a vtable? That is, could the "pointer to vtable" be null?' (what happens? it points to a 0 entry table?)
> 
> Luís

Question 1) is easy... I meant to indicate that both A and B should be left intact. If you really want to remove one then use this instead:

  align(4) // guarantee reserved is actually first
  struct NotDObject
  {
     int reservered = 0;
     // anything you want follows here
  }

Question 2) is a bit trickier. I am honestly not very clear on the specifics of how polymorphism is handled down at the level of the vtable. However I do know vtables are required for polymorphism and should be a real cause for surprise if you ever have an Object instance without a vtable given the D ABI docs.

However I feel I should make clear that only a class instance will have a vtable. Structs are just raw aggregates of data and will never contain a vtable. Inheritance is not allowed for structs.

Good luck!
August 17, 2006
Luís Marques wrote:
> BCS wrote:
> 
>> void* ptr;
>> // set ptr;
>> if(null !is cast(Object)ptr)
>> {
>>     // ptr is an object
>> }
>>
>> This should work because type checking is done on object up cast.
>>
>> However it dosn't seem to work.
> 
> 
> According to my experience, from void* to any type it always works. Only from Object to subclasses (or among other types, I guess) it actually does type checking. So if you want to force a cast to another incompatible classe you can do "cast(OtherClass)cast(void*)".
> 
> Luís

casting works but the result is invalid.

This OTOH

cast(Derived)cast(Object)v;

seg-v's on a struct.

Should this be a bug?
August 17, 2006
> Question 2) is a bit trickier. I am honestly not very clear on the specifics of how polymorphism is handled down at the level of the vtable. However I do know vtables are required for polymorphism and should be a real cause for surprise if you ever have an Object instance without a vtable given the D ABI docs.

It can't happen - Object is the base class of all other classes and has several virtual methods itself, so any object is guaranteed to have a vtable (if only Object's).


xs0
« First   ‹ Prev
1 2