www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - get address of object if opCast is overridden

reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
Let O be an object with opCast overridden, then


writeln(O); //prints string
writeln(cast(void *)O)) // error, works fine if I comment out the 
opCast override
writeln(&O) // address of pointer to O, not what I want.

I want to compare a few objects based on their location. (I know 
this is bad because of the GC, but I will probably pin them if I 
go this route)

It seems I have a difficult time getting the original behavior 
when something is syntactically overridden in D. I understand the 
point of cast(void *) not working when opCast is overridden but I 
then do not know how to still get the address.

Any Ideas?
Nov 30 2012
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Saturday, December 01, 2012 03:05:00 js.mdnq wrote:
 Let O be an object with opCast overridden, then
 
 
 writeln(O); //prints string
 writeln(cast(void *)O)) // error, works fine if I comment out the
 opCast override
 writeln(&O) // address of pointer to O, not what I want.
 
 I want to compare a few objects based on their location. (I know
 this is bad because of the GC, but I will probably pin them if I
 go this route)
 
 It seems I have a difficult time getting the original behavior
 when something is syntactically overridden in D. I understand the
 point of cast(void *) not working when opCast is overridden but I
 then do not know how to still get the address.
 
 Any Ideas?

For the moment, you're probably screwed. Certainly, if you overload opCast, then none of the normal casts work any more, which is a definite bug: http://d.puremagic.com/issues/show_bug.cgi?id=5747 So, unless there's a way to do it without a cast, you're stuck. And I have no idea how you could possibly do it without a cast. - Jonathan M Davis
Nov 30 2012
prev sibling next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 12/01/12 03:48, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 03:05:00 js.mdnq wrote:
 Let O be an object with opCast overridden, then


 writeln(O); //prints string
 writeln(cast(void *)O)) // error, works fine if I comment out the
 opCast override
 writeln(&O) // address of pointer to O, not what I want.

 I want to compare a few objects based on their location. (I know
 this is bad because of the GC, but I will probably pin them if I
 go this route)

 It seems I have a difficult time getting the original behavior
 when something is syntactically overridden in D. I understand the
 point of cast(void *) not working when opCast is overridden but I
 then do not know how to still get the address.

 Any Ideas?

For the moment, you're probably screwed. Certainly, if you overload opCast, then none of the normal casts work any more, which is a definite bug: http://d.puremagic.com/issues/show_bug.cgi?id=5747 So, unless there's a way to do it without a cast, you're stuck. And I have no idea how you could possibly do it without a cast.

*cast(void**)&O // assuming O is a class artur
Dec 01 2012
prev sibling next sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Saturday, 1 December 2012 at 11:06:02 UTC, Artur Skawina wrote:
 On 12/01/12 03:48, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 03:05:00 js.mdnq wrote:
 Let O be an object with opCast overridden, then


 writeln(O); //prints string
 writeln(cast(void *)O)) // error, works fine if I comment out 
 the
 opCast override
 writeln(&O) // address of pointer to O, not what I want.

 I want to compare a few objects based on their location. (I 
 know
 this is bad because of the GC, but I will probably pin them 
 if I
 go this route)

 It seems I have a difficult time getting the original behavior
 when something is syntactically overridden in D. I understand 
 the
 point of cast(void *) not working when opCast is overridden 
 but I
 then do not know how to still get the address.

 Any Ideas?

For the moment, you're probably screwed. Certainly, if you overload opCast, then none of the normal casts work any more, which is a definite bug: http://d.puremagic.com/issues/show_bug.cgi?id=5747 So, unless there's a way to do it without a cast, you're stuck. And I have no idea how you could possibly do it without a cast.

*cast(void**)&O // assuming O is a class artur

Duh! I should have been able to think of that ;/ Thanks.
Dec 01 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, December 01, 2012 12:05:49 Artur Skawina wrote:
 So, unless there's a way to do it without a cast, you're stuck. And I have
 no idea how you could possibly do it without a cast.

*cast(void**)&O // assuming O is a class

Are you sure? I'd be _very_ wary of that, because references aren't the same as pointers. I don't believe that there's any guarantee whatsoever that that will work, even if it happens to work now (which it may or may not). - Jonathan M Davis
Dec 01 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/01/2012 06:23 PM, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 12:05:49 Artur Skawina wrote:
 So, unless there's a way to do it without a cast, you're stuck. And I have
 no idea how you could possibly do it without a cast.

*cast(void**)&O // assuming O is a class

Are you sure? I'd be _very_ wary of that, because references aren't the same as pointers. I don't believe that there's any guarantee whatsoever that that will work, even if it happens to work now (which it may or may not). - Jonathan M Davis

Certainly works now. Another workaround that would keep working if class references were not pointers is: ((Object o)=>cast(void*)o)(O) // assuming O is the class object
Dec 01 2012
next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 12/01/12 20:26, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 18:43:22 Timon Gehr wrote:
 On 12/01/2012 06:23 PM, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 12:05:49 Artur Skawina wrote:
 So, unless there's a way to do it without a cast, you're stuck. And I
 have
 no idea how you could possibly do it without a cast.


Are you sure? I'd be _very_ wary of that, because references aren't the same as pointers. I don't believe that there's any guarantee whatsoever that that will work, even if it happens to work now (which it may or may not). - Jonathan M Davis

Certainly works now. Another workaround that would keep working if class references were not pointers is: ((Object o)=>cast(void*)o)(O) // assuming O is the class object

Ah, good point. Using Object would work just fine and doesn't rely on the implementation details of references.

References not appearing as if they were pointers is less likely than Object growing an opCast... Another workaround (for both non-empty classes and structs) would be cast(void*)&O.tupleof[0]-O.tupleof[0].offsetof which will let you not worry about that kind of potential changes to the core of the language. :) Seriously though, if one only needs to compare the addresses of class objects, "is" may be a better solution. artur
Dec 01 2012
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 12/02/12 14:25, js.mdnq wrote:
 On Saturday, 1 December 2012 at 23:57:27 UTC, Artur Skawina wrote:
 On 12/01/12 20:26, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 18:43:22 Timon Gehr wrote:
 On 12/01/2012 06:23 PM, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 12:05:49 Artur Skawina wrote:
 So, unless there's a way to do it without a cast, you're stuck. And I
 have
 no idea how you could possibly do it without a cast.


Are you sure? I'd be _very_ wary of that, because references aren't the same as pointers. I don't believe that there's any guarantee whatsoever that that will work, even if it happens to work now (which it may or may not). - Jonathan M Davis

Certainly works now. Another workaround that would keep working if class references were not pointers is: ((Object o)=>cast(void*)o)(O) // assuming O is the class object

Ah, good point. Using Object would work just fine and doesn't rely on the implementation details of references.

References not appearing as if they were pointers is less likely than Object growing an opCast... Another workaround (for both non-empty classes and structs) would be cast(void*)&O.tupleof[0]-O.tupleof[0].offsetof which will let you not worry about that kind of potential changes to the core of the language. :) Seriously though, if one only needs to compare the addresses of class objects, "is" may be a better solution.

I'm not just comparing them but using them as a unique ID for the objects in an algorithm to prevent computing over the same object more than once.

int[typeof(O)] rc; rc[O] = 42; auto O2 = O; // [...] if (auto r = O2 in rc) return *r; else return rc[O2] = compute(O2); IOW explicitly taking the address may not be necessary when doing that kind of things. Of course sometimes it /is/ necessary. This is is d.learn, and the how-to-get-class- -instance-address subthread could have pointed somebody into the wrong direction, that's all. artur
Dec 02 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, December 01, 2012 18:43:22 Timon Gehr wrote:
 On 12/01/2012 06:23 PM, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 12:05:49 Artur Skawina wrote:
 So, unless there's a way to do it without a cast, you're stuck. And I
 have
 no idea how you could possibly do it without a cast.
 


Are you sure? I'd be _very_ wary of that, because references aren't the same as pointers. I don't believe that there's any guarantee whatsoever that that will work, even if it happens to work now (which it may or may not). - Jonathan M Davis

Certainly works now. Another workaround that would keep working if class references were not pointers is: ((Object o)=>cast(void*)o)(O) // assuming O is the class object

Ah, good point. Using Object would work just fine and doesn't rely on the implementation details of references. - Jonathan M Davis
Dec 01 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, December 02, 2012 00:57:14 Artur Skawina wrote:
 Seriously though, if one only needs to compare the addresses of class
 objects, "is" may be a better solution.

Is that all that was being done? I obviously missed that one way or another. Yeah, that's what the is operator is for. - Jonathan M Davis
Dec 01 2012
prev sibling parent "js.mdnq" <js_adddot+mdng gmail.com> writes:
On Saturday, 1 December 2012 at 23:57:27 UTC, Artur Skawina wrote:
 On 12/01/12 20:26, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 18:43:22 Timon Gehr wrote:
 On 12/01/2012 06:23 PM, Jonathan M Davis wrote:
 On Saturday, December 01, 2012 12:05:49 Artur Skawina wrote:
 So, unless there's a way to do it without a cast, you're 
 stuck. And I
 have
 no idea how you could possibly do it without a cast.


Are you sure? I'd be _very_ wary of that, because references aren't the same as pointers. I don't believe that there's any guarantee whatsoever that that will work, even if it happens to work now (which it may or may not). - Jonathan M Davis

Certainly works now. Another workaround that would keep working if class references were not pointers is: ((Object o)=>cast(void*)o)(O) // assuming O is the class object

Ah, good point. Using Object would work just fine and doesn't rely on the implementation details of references.

References not appearing as if they were pointers is less likely than Object growing an opCast... Another workaround (for both non-empty classes and structs) would be cast(void*)&O.tupleof[0]-O.tupleof[0].offsetof which will let you not worry about that kind of potential changes to the core of the language. :) Seriously though, if one only needs to compare the addresses of class objects, "is" may be a better solution. artur

I'm not just comparing them but using them as a unique ID for the objects in an algorithm to prevent computing over the same object more than once.
Dec 02 2012