 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Thu Sep 17, 2009 2:43 am Post subject: "this" pointer changed? |
|
|
This is really more a general programming question, but it's a PSP application, so I thought I'd ask here. For starters, I have the following class:
| Code: |
class Viewpoint
{
public:
Viewpoint(int source) { Viewpoint(source, 0, 0, 0); }
Viewpoint(int source, float zoom, float lon, float lat);
void Scroll(float x, float y);
void Zoom(float step);
void Project(int &tx, int &ty, int &tz, int &ts, int &px, int &py);
int source; float zoom, scale, lon, lat;
};
|
Now, in my main function, I create a Viewpoint, and call Project on it each frame. Since it was giving me strange results (usually crashes!), I added some debug messages, and got this in my output:
| Code: |
Viewpoint.cpp:45: Viewpoint::Viewpoint(0x9fbfd88): zoom == 0.000000, scale == 1.000000, lon == 0.000000, lat == -0.000046
Viewpoint.cpp:87: Viewpoint::Project(0x9fbfddc): zoom == 0.000000, scale == 0.000000
|
The values in parentheses are the "this" pointer at each call. What I don't understand is why, when I only created one Viewpoint in the entire program, "this" has a different value in Project than it did in the constructor? I've tried creating it on the stack and on the heap, but it happens in both cases, and I've never seen it before. |
|
| Back to top |
|
 |
jbit Site Admin

Joined: 28 May 2005 Posts: 293 Location: København, Danmark
|
Posted: Thu Sep 17, 2009 3:11 am Post subject: |
|
|
Without more code it's impossible to tell.... However it could be memory corruption (over running a buffer?) or pointer screw up.. but since the pointers are quite close together my guess is you're doing something like...
| Code: | Viewpoint *view = new Viewpoint();
view++;
view->Project(); |
|
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Thu Sep 17, 2009 3:29 am Post subject: |
|
|
But I don't have any pointer manipulations. The section where it's used looks like this (parts removed for brevity):
| Code: |
Viewpoint view(0);
while (running)
{
// update animations, etc.
if (pressed(PSP_CTRL_LEFT)) view.Scroll(-1, 0);
if (pressed(PSP_CTRL_RIGHT)) view.Scroll(+1, 0);
if (pressed(PSP_CTRL_UP)) view.Scroll(0, -1);
if (pressed(PSP_CTRL_DOWN)) view.Scroll(0, +1);
if (pressed(PSP_CTRL_LTRIGGER)) view.Zoom(-1);
if (pressed(PSP_CTRL_RTRIGGER)) view.Zoom(+1);
int tx, ty, tz, ts, px, py;
view.Project(tx, ty, tz, ts, px, py);
startDrawing();
for (int j = -1; j <= 1; j++)
{
for (int i = -1; i <= 1; i++)
{
getTile(view.source, tz, tx + i, ty + j)->Draw(px + i*ts, py + j*ts, ts, ts);
}
}
// show coordinate info
endDrawing();
swapBuffers();
}
|
The code worked fine with a struct, but it was a little messy, so I was trying to get some encapsulation going. I don't want to go back if I can help it, though. |
|
| Back to top |
|
 |
psPea
Joined: 01 Sep 2007 Posts: 64
|
Posted: Thu Sep 17, 2009 4:23 am Post subject: |
|
|
I think | Code: | Viewpoint(int source) { Viewpoint(source, 0, 0, 0); }
Viewpoint(int source, float zoom, float lon, float lat); | looks very messy, you should use | Code: | | Viewpoint(int source, float zoom = 0, float lon = 0, float lat = 0); | instead _________________ Click ME! |
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Thu Sep 17, 2009 6:01 am Post subject: |
|
|
Well, it's been a while since I've used C++ to this extent, I guess I'm used to the C# way of doing it. :)
EDIT: Added more debug messages, and now it seems that the constructor is the only place where "this" points somewhere different. All other calls have the same address as the "real" address of the object.
Could I have just been (un)lucky enough to stumble on an obscure compiler bug? As I said, I have never seen this happen before; I have half a dozen other classes in my project, and none of them has exhibited the same problem.
I also found a little workaround that is helping, but I'm still curious about why this happened. |
|
| Back to top |
|
 |
psPea
Joined: 01 Sep 2007 Posts: 64
|
Posted: Thu Sep 17, 2009 9:59 am Post subject: |
|
|
Maybe this is only initialized after the constructor returns. _________________ Click ME! |
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Thu Sep 17, 2009 10:44 am Post subject: |
|
|
| psPea wrote: | | Maybe this is only initialized after the constructor returns. |
I think it's supposed to be an idiom/placeholder rather than an actual variable to be "initialized." So it should point to "this" object no matter when it's used. Right? |
|
| Back to top |
|
 |
jbit Site Admin

Joined: 28 May 2005 Posts: 293 Location: København, Danmark
|
Posted: Thu Sep 17, 2009 5:35 pm Post subject: |
|
|
Ugh, didn't notice you were doing odd things..... calling a constructor C# style does not do what you think it does! | Code: | class Test
{
int m_iVar;
public:
Test(int var)
{
printf("fake: %p\n", this);
m_iVar = var;
}
Test()
{
m_iVar = 0;
printf("mine: %p\n", this);
Test(1);
}
void foo()
{
printf("using: %p (%d)\n", this, m_iVar);
}
};
int main()
{
Test t;
t.foo();
} | prints | Code: | mine: 0xbffff8cc
fake: 0xbffff89c
using: 0xbffff8cc (0) |
The constructor call inside the constructor makes a new object on the stack, calls the constructor on that, and then deletes it....
edit: Also, I can't see this working in C# either, as far as I know the only way to do this in C# would be constructor chaining which is: | Code: | class Test
{
int m_iVar;
public:
Test(int var) { m_iVar = var; }
Test() : this(1) {}
}; |
But as said above, the preferred (and simplest) way for this specific use case is to use default arguments ( Test(int var = 1) ). |
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Thu Sep 17, 2009 11:18 pm Post subject: |
|
|
| jbit wrote: | | The constructor call inside the constructor makes a new object on the stack, calls the constructor on that, and then deletes it.... |
>.< That explains it, then.
| jbit wrote: | | edit: Also, I can't see this working in C# either, as far as I know the only way to do this in C# would be constructor chaining |
That's what I was trying to do, but I couldn't remember the C++ syntax (and was too busy/lazy/distracted at the time to JFGI). Since what I wrote compiled, I thought I'd gotten it.
EDIT: And now having done so, I learn that there is no syntax for it. Bah. :P
Thanks for your help. :) |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|