www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - cast(size_t)&c != 0, but c is null

reply "simendsjo" <simendsjo gmail.com> writes:
Very newbie question coming up :)

How does D mark null values for classes?
`c is null` returns true, but `&c` isn't 0.
So how does D know `c is null`?

class C {}
C c;
assert(c is null);
assert(cast(size_t)&c == 0); // fails.
May 14 2013
next sibling parent reply "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
On Tuesday, 14 May 2013 at 12:18:20 UTC, simendsjo wrote:
 Very newbie question coming up :)

 How does D mark null values for classes?
 `c is null` returns true, but `&c` isn't 0.
 So how does D know `c is null`?

 class C {}
 C c;
 assert(c is null);
 assert(cast(size_t)&c == 0); // fails.
That's the address of the reference. If you want the address of the object: assert(cast(size_t)cast(void*)c == 0); // passes
May 14 2013
parent "simendsjo" <simendsjo gmail.com> writes:
On Tuesday, 14 May 2013 at 12:20:00 UTC, Andrej Mitrovic wrote:
 On Tuesday, 14 May 2013 at 12:18:20 UTC, simendsjo wrote:
 Very newbie question coming up :)

 How does D mark null values for classes?
 `c is null` returns true, but `&c` isn't 0.
 So how does D know `c is null`?

 class C {}
 C c;
 assert(c is null);
 assert(cast(size_t)&c == 0); // fails.
That's the address of the reference. If you want the address of the object: assert(cast(size_t)cast(void*)c == 0); // passes
Ah. Thanks to you both. Now I have some strange bug where somewhere in my code (probably using alias for passing symbols to templates), it get's a "wrong" reference...
May 14 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Tuesday, 14 May 2013 at 12:18:20 UTC, simendsjo wrote:
 Very newbie question coming up :)

 How does D mark null values for classes?
 `c is null` returns true, but `&c` isn't 0.
 So how does D know `c is null`?

 class C {}
 C c;
 assert(c is null);
 assert(cast(size_t)&c == 0); // fails.
"&c" is address of reference, no class instance. I don't know if there is a way to get a pointer to class instance in D but I am not aware of one.
May 14 2013
parent reply David <d dav1d.de> writes:
Am 14.05.2013 14:24, schrieb Dicebot:
 On Tuesday, 14 May 2013 at 12:18:20 UTC, simendsjo wrote:
 Very newbie question coming up :)

 How does D mark null values for classes?
 `c is null` returns true, but `&c` isn't 0.
 So how does D know `c is null`?

 class C {}
 C c;
 assert(c is null);
 assert(cast(size_t)&c == 0); // fails.
"&c" is address of reference, no class instance. I don't know if there is a way to get a pointer to class instance in D but I am not aware of one.
A simple cast to void* should do it: cast(void*)c
May 15 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 15 May 2013 at 10:31:29 UTC, David wrote:
 "&c" is address of reference, no class instance. I don't know 
 if there
 is a way to get a pointer to class instance in D but I am not 
 aware of one.
A simple cast to void* should do it: cast(void*)c
Is it actually defined somewhere in spec?
May 15 2013
parent reply Artur Skawina <art.08.09 gmail.com> writes:
On 05/15/13 13:04, Dicebot wrote:
 On Wednesday, 15 May 2013 at 10:31:29 UTC, David wrote:
 "&c" is address of reference, no class instance. I don't know if there
 is a way to get a pointer to class instance in D but I am not aware of one.
A simple cast to void* should do it: cast(void*)c
class C { auto opCast(T:void*)() { return null; } } So - no - a simple cast to void* won't always work, as the op can be overloaded, even if only by accident. See also: http://forum.dlang.org/thread/mutvhrrdfzunbrhmvztp forum.dlang.org#post-mailman.2432.1354406246.5162.digitalmars-d-learn:40puremagic.com and http://d.puremagic.com/issues/show_bug.cgi?id=8545 artur
May 15 2013
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 15 May 2013 11:08:33 -0400, Artur Skawina <art.08.09 gmail.com>  
wrote:

 On 05/15/13 13:04, Dicebot wrote:
 On Wednesday, 15 May 2013 at 10:31:29 UTC, David wrote:
 "&c" is address of reference, no class instance. I don't know if there
 is a way to get a pointer to class instance in D but I am not aware  
 of one.
A simple cast to void* should do it: cast(void*)c
class C { auto opCast(T:void*)() { return null; } } So - no - a simple cast to void* won't always work, as the op can be overloaded, even if only by accident.
You can insert a cast to Object first. -Steve
May 15 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
 You can insert a cast to Object first.
doesn't seem to work. I'm trying to write a generic solution but having an innocent 'T opCast(T : int)() { return 1; }' breaks it, see Error below. doesn't seem to work. This seems to call for a compiler solution? import std.stdio; import std.conv; void*AddressOf(T)(T a) if(is(T==class)){ return cast(void*)cast(Object) a;//Error: template instance opCast!( Object) opCast!(Object) does not match template declaration opCast(T : int)( ) } T*AddressOf(T)(ref T a) if(!is(T==class)){ return &a; } class A{ int x; T opCast(T : int)() { return 1; } // int opCast(T:void*)() { return 1; } //won't work either } struct B{ } void main(){ A a; writeln(AddressOf(a)); a = new A; writeln(AddressOf(a)); B b; writeln(AddressOf(b)); B*b2; writeln(AddressOf(*b2)); // writeln(AddressOf(B.init)); //waiting for rvalue ref, DIP39 } On Wed, May 15, 2013 at 11:30 AM, Steven Schveighoffer <schveiguy yahoo.com>wrote:
 On Wed, 15 May 2013 11:08:33 -0400, Artur Skawina <art.08.09 gmail.com>
 wrote:

  On 05/15/13 13:04, Dicebot wrote:
 On Wednesday, 15 May 2013 at 10:31:29 UTC, David wrote:

 "&c" is address of reference, no class instance. I don't know if there
 is a way to get a pointer to class instance in D but I am not aware of
 one.
A simple cast to void* should do it: cast(void*)c
class C { auto opCast(T:void*)() { return null; } } So - no - a simple cast to void* won't always work, as the op can be overloaded, even if only by accident.
You can insert a cast to Object first. -Steve
May 15 2013
next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
15-May-2013 23:17, Timothee Cour пишет:
  >> You can insert a cast to Object first.

 doesn't seem to work.
 I'm trying to write a generic solution but having an innocent
 'TopCast(T:int)(){return1;}' breaks it, see Error below.
 doesn't seem to work.

 This seems to call for a compiler solution?
Won't this work? *cast(void**)&object
 importstd.stdio;
 importstd.conv;


 void*AddressOf(T)(Ta)if(is(T==class)){
 returncast(void*)cast(Object)a;//Error:templateinstanceopCast!(Object)opCast!(Object)doesnotmatchtemplatedeclarationopCast(T:int)()
 }
 T*AddressOf(T)(refTa)if(!is(T==class)){
 return&a;
 }
 classA{
 intx;
 TopCast(T:int)(){return1;}
 //intopCast(T:void*)(){return1;} //won't work either
 }
 structB{

 }
 voidmain(){
 Aa;
 writeln(AddressOf(a));
 a=newA;
 writeln(AddressOf(a));

 Bb;
 writeln(AddressOf(b));
 B*b2;
 writeln(AddressOf(*b2));
 //writeln(AddressOf(B.init));//waitingforrvalueref,DIP39
 }


 On Wed, May 15, 2013 at 11:30 AM, Steven Schveighoffer
 <schveiguy yahoo.com <mailto:schveiguy yahoo.com>> wrote:

     On Wed, 15 May 2013 11:08:33 -0400, Artur Skawina
     <art.08.09 gmail.com <mailto:art.08.09 gmail.com>> wrote:

         On 05/15/13 13:04, Dicebot wrote:

             On Wednesday, 15 May 2013 at 10:31:29 UTC, David wrote:

                     "&c" is address of reference, no class instance. I
                     don't know if there
                     is a way to get a pointer to class instance in D but
                     I am not aware of one.


                 A simple cast to void* should do it: cast(void*)c


             class C { auto opCast(T:void*)() { return null; } }

         So - no - a simple cast to void* won't always work, as the op can be
         overloaded, even if only by accident.


     You can insert a cast to Object first.

     -Steve
-- Dmitry Olshansky
May 15 2013
next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
 Won't this work?
 *cast(void**)&object


great, works! I've added it to my dtools repo: https://github.com/timotheecour/dtools/blob/master/dtools/util/util.d#L19
May 15 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 15 May 2013 at 19:30:41 UTC, Dmitry Olshansky wrote:
 Won't this work?
 *cast(void**)&object
Right question is "is this guaranteed to work by spec?".
May 16 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 16 May 2013 at 09:05:46 UTC, Dicebot wrote:
 On Wednesday, 15 May 2013 at 19:30:41 UTC, Dmitry Olshansky 
 wrote:
 Won't this work?
 *cast(void**)&object
Right question is "is this guaranteed to work by spec?".
Spec is silent about this but in practice this should work. Real question is here why would you want "pointer to class" when you have normal reference and what such "pointer" would give you.
May 16 2013
next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
interface with C++ for example (for example extern(C++) classes )

On Thu, May 16, 2013 at 2:31 AM, Maxim Fomin <maxim maxim-fomin.ru> wrote:

 On Thursday, 16 May 2013 at 09:05:46 UTC, Dicebot wrote:

 On Wednesday, 15 May 2013 at 19:30:41 UTC, Dmitry Olshansky wrote:

 Won't this work?
 *cast(void**)&object
Right question is "is this guaranteed to work by spec?".
Spec is silent about this but in practice this should work. Real question is here why would you want "pointer to class" when you have normal reference and what such "pointer" would give you.
May 16 2013
prev sibling next sibling parent "Dicebot" <m.strashun gmail.com> writes:
On Thursday, 16 May 2013 at 09:31:11 UTC, Maxim Fomin wrote:
 On Thursday, 16 May 2013 at 09:05:46 UTC, Dicebot wrote:
 On Wednesday, 15 May 2013 at 19:30:41 UTC, Dmitry Olshansky 
 wrote:
 Won't this work?
 *cast(void**)&object
Right question is "is this guaranteed to work by spec?".
Spec is silent about this but in practice this should work. Real question is here why would you want "pointer to class" when you have normal reference and what such "pointer" would give you.
Then spec needs to be updated or this is not correct solution.
May 16 2013
prev sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
16-May-2013 13:31, Maxim Fomin пишет:
 On Thursday, 16 May 2013 at 09:05:46 UTC, Dicebot wrote:
 On Wednesday, 15 May 2013 at 19:30:41 UTC, Dmitry Olshansky wrote:
 Won't this work?
 *cast(void**)&object
Right question is "is this guaranteed to work by spec?".
Spec is silent about this but in practice this should work. Real question is here why would you want "pointer to class" when you have normal reference and what such "pointer" would give you.
Since class is a reference it's a pointer value (address anyhow). Hence you'll get an address of value holding that address (e.g. of a temporary) then dereference it as void** pointer. It's sometimes useful in this particular case to circumvent type-system in order to do smth (interface with C etc.). -- Dmitry Olshansky
May 16 2013
prev sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
 //    writeln(AddressOf(B.init)); //waiting for rvalue ref, 
 DIP39
Did I miss something? Since when is sure that the DIP is implemented? o.O
May 15 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
On Wed, May 15, 2013 at 12:35 PM, Namespace <rswhite4 googlemail.com> wrote:

 //    writeln(AddressOf(B.init)); //waiting for rvalue ref, DIP39

 Did I miss something? Since when is sure that the DIP is implemented? o.O
just wishful thinking :) actually this should've been: // writeln(AddressOf(B.init^)); //waiting for rvalue ref, DIP39
May 15 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 15 May 2013 at 20:15:26 UTC, Timothee Cour wrote:
 On Wed, May 15, 2013 at 12:35 PM, Namespace 
 <rswhite4 googlemail.com> wrote:

 //    writeln(AddressOf(B.init)); //waiting for rvalue ref, 
 DIP39

 Did I miss something? Since when is sure that the DIP is 
 implemented? o.O
just wishful thinking :) actually this should've been: // writeln(AddressOf(B.init^)); //waiting for rvalue ref, DIP39
I know that feeling. :D But I doubt that D will have such a thing some day. But: good luck, it is about time that D catch up fully to C++. :)
May 15 2013
prev sibling parent David <d dav1d.de> writes:
Am 15.05.2013 17:08, schrieb Artur Skawina:
 On 05/15/13 13:04, Dicebot wrote:
 On Wednesday, 15 May 2013 at 10:31:29 UTC, David wrote:
 "&c" is address of reference, no class instance. I don't know if there
 is a way to get a pointer to class instance in D but I am not aware of one.
A simple cast to void* should do it: cast(void*)c
class C { auto opCast(T:void*)() { return null; } } So - no - a simple cast to void* won't always work, as the op can be overloaded, even if only by accident. See also: http://forum.dlang.org/thread/mutvhrrdfzunbrhmvztp forum.dlang.org#post-mailman.2432.1354406246.5162.digitalmars-d-learn:40puremagic.com and http://d.puremagic.com/issues/show_bug.cgi?id=8545 artur
Overloading cast is broken and shouldn't be in the language (imo). Why broken? If you only want to overload cast(bool) (for if(x) which calls if(cast(bool)x -> x.opCast!bool()) you have to overload all other possible casts, otherwise compiler will complain that this cast is no overloaded. Also overloading a cast doesn't really make any sense (except the bool case), that's also the reason why I really hate std.conv.to's new behaviour of calling opCast, this makes no sense, to! does a conversion not a cast.
May 16 2013