Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 17, 2006 determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to nobody | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 Re: determining if a void* points to a valid Object | ||||
---|---|---|---|---|
| ||||
Posted in reply to nobody |
> 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
|
Copyright © 1999-2021 by the D Language Foundation