digitalmars.D - determining if a void* points to a valid Object
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (16/16) Aug 17 2006 Hello all,
- Sean Kelly (7/21) Aug 17 2006 It would be a horrible hack, but you might be able to test whether the
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (15/20) Aug 17 2006 http://www.digitalmars.com/d/abi.html tells us:
- BCS (10/32) Aug 17 2006 void* ptr;
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (6/16) Aug 17 2006 According to my experience, from void* to any type it always works. Only...
- BCS (6/26) Aug 17 2006 casting works but the result is invalid.
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (5/14) Aug 17 2006 How are you doing that? if v is a struct than casting it to Object fails...
- BCS (26/43) Aug 19 2006 The bug is the Seg-v on the /second/ cast, IMHO trying to cast a pointer...
- nobody (23/45) Aug 17 2006 D Application Binary Interface
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (6/24) Aug 17 2006 Yes, that's exactly what I need (thanks).
- nobody (17/44) Aug 17 2006 Question 1) is easy... I meant to indicate that both A and B should be l...
- xs0 (4/9) Aug 17 2006 It can't happen - Object is the base class of all other classes and has
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (8/11) Aug 17 2006 Okay, thanks for the great info!
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
Aug 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
Aug 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
Aug 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 Marquesvoid* 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.
Aug 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
Aug 17 2006
Luís Marques wrote:BCS wrote: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?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
Aug 17 2006
BCS wrote: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?How are you doing that? if v is a struct than casting it to Object fails (it does here...). If you cast it to void* first than that would be your way of saying "I know what I'm doing", so I guess it wouldn't be a bug (not the case, right?).
Aug 17 2006
Luís Marques wrote:BCS wrote:The bug is the Seg-v on the /second/ cast, IMHO trying to cast a pointer shoud never seg-v if the pointer points to valid data What the code is trying to say is: "Take this void* and pretend it is an Object. Now cast it to Derived with the dynamic_cast like checking." The problem (I assume) is that the way that the cast check is done assumes that the pointer is pointing to an Object. This might be because it is using something in the v-tbl to do the checking, for instance: <code> Object o; auto d = cast(Derived)o; // in effect: auto d = o.__CastToSomething(Derived.typeid); </code> this fails if o[0] isn't a valid v-tbl a more robust system would use something like: <code> auto d = cast(Derived)o; // in effect: auto d = Derived.__CastFromSomething(o); </code> where __CastFromSomething only requiters o to be a valid pointer. This could be done by having __CastFromSomething check if o[0] is a known v-tbl for Derived or one of it's descendants. This has the problem that making the table for __CastFromSomething can't be done at compile time because Derived won't known about all of it's descendants. Crud, now this is getting into ABI design...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?How are you doing that? if v is a struct than casting it to Object fails (it does here...). If you cast it to void* first than that would be your way of saying "I know what I'm doing", so I guess it wouldn't be a bug (not the case, right?).
Aug 19 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 MarquesD 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
Aug 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 // ObjectYes, 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
Aug 17 2006
Luís Marques wrote:nobody wrote: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!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 // ObjectYes, 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
Aug 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
Aug 17 2006
xs0 wrote: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).Okay, thanks for the great info! Btw: should this have been asked in D.learn? When I posted I felt that this might be going a bit too low-level for D.learn, but I guess "nobody" is probably right. PS: I am not able to follow the newsgroups during most of the day anyway, since the web interface is down :( Luís
Aug 17 2006