digitalmars.D.learn - &this pointer
- e-t172 (53/53) Feb 10 2007 Hi,
- Bill Baxter (8/78) Feb 10 2007 By reference it means that 'this' already *is* a pointer.
- Frits van Bommel (14/20) Feb 10 2007 Wrong.
- e-t172 (3/15) Feb 10 2007 Thank you very much :)
- Derek Parnell (11/11) Feb 10 2007 The phrase "&this" returns the address of the hidden 'this' parameter
- e-t172 (21/21) Feb 11 2007 The following does not work :
- Brian Byrne (4/33) Feb 11 2007 "this" is of type "Test". Therefore to recover it from a void*, do simpl...
- Derek Parnell (15/44) Feb 11 2007 You need "(cast(Test) ptr).foo();" instead.
Hi,
I'm a beginner with D, I've got some basis with C/C++ but I mainly
program with PHP. Ad far as I'm concerned, D is a very interesting
language, hence I started to develop a personal project in D to get a
clear idea of its features ; nonetheless, during my research, I've
noticed a behavior I considered very weird about the 'this' reference.
According to what I understood from the documentation, it is a reference
to the object itself, so coherently, &this should return the memory
address of the object itself.
It that is correct, could one explain that to me (compiled with DMD 1.0) :
---
import std.stdio;
import std.string;
class Test
{
this()
{
writefln("in this() itself - &this : ", &this);
foo("called from this(), first shot");
foo("called from this(), second shot");
}
void foo(char[] location)
{
writefln(location, " - foo() - &this : ", &this);
bar(location);
}
void bar(char[] location)
{
writefln(location, " - bar() - &this : ", &this);
}
}
int main()
{
auto test = new Test();
test.foo("called from main(), first shot");
test.foo("called from main(), second shot");
return 0;
}
---
$ ./test
in this() itself - &this : BFAE4394
called from this(), first shot - foo() - &this : BFAE4370
called from this(), first shot - bar() - &this : BFAE4344
called from this(), second shot - foo() - &this : BFAE4370
called from this(), second shot - bar() - &this : BFAE4344
called from main(), first shot - foo() - &this : BFAE438C
called from main(), first shot - bar() - &this : BFAE4360
called from main(), second shot - foo() - &this : BFAE438C
called from main(), second shot - bar() - &this : BFAE4360
---
In accordance with the output, the object location in memory endlessly
changes ?! I admit to be a little startled...
e-t172
Feb 10 2007
By reference it means that 'this' already *is* a pointer.
You don't need to take it's address. If you do you're just getting the
address of the pointer not the address of the object.
Try something like
writefln("%x",cast(void*)this);
if you really want to see the address of the object.
--bb
e-t172 wrote:
Hi,
I'm a beginner with D, I've got some basis with C/C++ but I mainly
program with PHP. Ad far as I'm concerned, D is a very interesting
language, hence I started to develop a personal project in D to get a
clear idea of its features ; nonetheless, during my research, I've
noticed a behavior I considered very weird about the 'this' reference.
According to what I understood from the documentation, it is a reference
to the object itself, so coherently, &this should return the memory
address of the object itself.
It that is correct, could one explain that to me (compiled with DMD 1.0) :
---
import std.stdio;
import std.string;
class Test
{
this()
{
writefln("in this() itself - &this : ", &this);
foo("called from this(), first shot");
foo("called from this(), second shot");
}
void foo(char[] location)
{
writefln(location, " - foo() - &this : ", &this);
bar(location);
}
void bar(char[] location)
{
writefln(location, " - bar() - &this : ", &this);
}
}
int main()
{
auto test = new Test();
test.foo("called from main(), first shot");
test.foo("called from main(), second shot");
return 0;
}
---
$ ./test
in this() itself - &this : BFAE4394
called from this(), first shot - foo() - &this : BFAE4370
called from this(), first shot - bar() - &this : BFAE4344
called from this(), second shot - foo() - &this : BFAE4370
called from this(), second shot - bar() - &this : BFAE4344
called from main(), first shot - foo() - &this : BFAE438C
called from main(), first shot - bar() - &this : BFAE4360
called from main(), second shot - foo() - &this : BFAE438C
called from main(), second shot - bar() - &this : BFAE4360
---
In accordance with the output, the object location in memory endlessly
changes ?! I admit to be a little startled...
e-t172
Feb 10 2007
e-t172 wrote:I've noticed a behavior I considered very weird about the 'this' reference. According to what I understood from the documentation, it is a reference to the object itself,Correct.so coherently, &this should return the memory address of the object itself.Wrong. A reference in D is different from a reference in C++. If you take the address of a reference in D, you do not get the address of the object referenced, but the address of the reference itself. Think of a D reference as a pointer to the body of the class, with small differences. For one, casting between references works differently. For another, pointer arithmetic doesn't work on references. But operators like (unary) & work the same: in this case, it returns a pointer to the memory storing the address being referred to. To get the address of the object from a reference you can cast it to void*. So in your case, replace "&this" with "cast(void*)this" and you will see the same address everywhere.
Feb 10 2007
Frits van Bommel a écrit :A reference in D is different from a reference in C++. If you take the address of a reference in D, you do not get the address of the object referenced, but the address of the reference itself. Think of a D reference as a pointer to the body of the class, with small differences. For one, casting between references works differently. For another, pointer arithmetic doesn't work on references. But operators like (unary) & work the same: in this case, it returns a pointer to the memory storing the address being referred to. To get the address of the object from a reference you can cast it to void*. So in your case, replace "&this" with "cast(void*)this" and you will see the same address everywhere.Thank you very much :) e-t172
Feb 10 2007
The phrase "&this" returns the address of the hidden 'this' parameter passed to the member functions. In other words, you are seeing the address of a parameter on the stack. If you are trying to get the address of the class instance, the phrase "cast(void *)this" seems to work, but I'm sure there are other techniques too. -- Derek Parnell Melbourne, Australia "Justice for David Hicks!" skype: derek.j.parnell
Feb 10 2007
The following does not work :
import std.stdio;
class Test
{
this()
{
void* ptr = cast(void*) this;
(*(cast(Test*) ptr)).foo();
}
void foo()
{
writefln("OK");
}
}
int main()
{
auto test = new Test();
return 0;
}
Result : segmentation fault
Could one explain why ?
Feb 11 2007
e-t172 wrote:
The following does not work :
import std.stdio;
class Test
{
this()
{
void* ptr = cast(void*) this;
(*(cast(Test*) ptr)).foo();
}
void foo()
{
writefln("OK");
}
}
int main()
{
auto test = new Test();
return 0;
}
Result : segmentation fault
Could one explain why ?
"this" is of type "Test". Therefore to recover it from a void*, do simply:
(cast(Test)ptr).foo();
Brian Byrne
Feb 11 2007
On Sun, 11 Feb 2007 21:14:26 +0100, e-t172 wrote:
The following does not work :
import std.stdio;
class Test
{
this()
{
void* ptr = cast(void*) this;
(*(cast(Test*) ptr)).foo();
}
void foo()
{
writefln("OK");
}
}
int main()
{
auto test = new Test();
return 0;
}
Result : segmentation fault
Could one explain why ?
You need "(cast(Test) ptr).foo();" instead.
This is because 'void* ptr' contains the address of the object, and when
calling object members, you need to use a /reference/ to the object and not
the object itself. Casting 'ptr' to 'Test*' just tells the compiler to
assume that 'ptr' points to a Test object and then using the '*' operator
returns the object and not a reference to the object.
If, however you had cast 'ptr' to just a 'Test', this tells the compiler to
assume that 'ptr' contains a reference to the object and so it can then
find the member to invoke.
--
Derek Parnell
Melbourne, Australia
"Justice for David Hicks!"
skype: derek.j.parnell
Feb 11 2007









Bill Baxter <dnewsgroup billbaxter.com> 