Jump to content
  • Advertisement
Sign in to follow this  
RealMarkP

[C++] Checking for 'this' inside it's class

This topic is 3381 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there a way that I can check if the 'this' keyword was passed into a class (either by checking if the pointer is on the stack, or something)? For example:
MyClass::someFunction()
{
  CSomeOtherClass foo(this);// check if 'this' was passed in as opposed to a pointer variable.
}

I know how to check if a pointer being passed in is on the Stack or the Heap but the 'this' keyword will always be on the Heap if the class itself was dynamically allocated. Is there a way to do this? Possibly using MSVC type traits or something?

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure I understand what you are trying to do, but `this' is always a pointer, and it's always passed to non-static member functions.

Share this post


Link to post
Share on other sites
I don't understand the question... can you perhaps give a concrete example of why you'd want to do this?

Share this post


Link to post
Share on other sites
I am also confused by the question. The thiscall calling convention always stores this in the ECX register, and it follows that you can't take the address of it. If you're already inside a member function and you attempt to call a member function on another instance, then ECX will be pushed onto the stack first so that it can be restored. Also, with thiscall all parameters are pushed onto the stack. But again, I'm still not completely clear on your question.

As others have asked, what exactly is it you're trying to do?

Share this post


Link to post
Share on other sites
You can always check if this == 0

see if it's null.

not sure if that answers your question though either.

the "this" parameter is a hidden argument in your member functions.

IE if you have a member function void Blah(void), in reality (under the hood) the function is void Blah(MyClass *this)

Share this post


Link to post
Share on other sites
I think he's wanting to see if the instance of the class was allocated on the heap (via new, for instance), or whether it was allocated on the stack (passed by value, for instance)

Since you would only have 'this' be on the stack when inside a member function of a class that was passed by value to some function further up the call stack, and the stack grows downwards, I suppose you could check for stack allocation by seeing if 'this' is greater than the current stack pointer... but I'm no expert.

Do you guys thing this is a valid approach for the OP to take?

Share this post


Link to post
Share on other sites
Quote:
Original post by Ravyne
I think he's wanting to see if the instance of the class was allocated on the heap (via new, for instance), or whether it was allocated on the stack (passed by value, for instance)

Since you would only have 'this' be on the stack when inside a member function of a class that was passed by value to some function further up the call stack, and the stack grows downwards, I suppose you could check for stack allocation by seeing if 'this' is greater than the current stack pointer... but I'm no expert.

Do you guys thing this is a valid approach for the OP to take?

The OP mentioned that he already knew how to check if a "pointer being passed in" was on on the stack or heap, but again it wasn't really clear what they meant. I was going to suggest using GetProcessHeap() to get some information on the size and location of the heap and check against that, but it certainly isn't portable and probably not a good idea in general anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ravyne
I think he's wanting to see if the instance of the class was allocated on the heap (via new, for instance), or whether it was allocated on the stack (passed by value, for instance)
But why would you want to do that anyway?

Share this post


Link to post
Share on other sites
Quote:
Original post by RealMarkP
Is there a way to do this?

No. Consider this code:

struct MyClass {
void bar(void);
};

void foo(MyClass * ptr) {
// magic that determines if ptr was this or not
}

void MyClass::bar(void) {
foo(this);
}

void baz1(MyClass * f) {
f->bar();
}

void baz2(MyClass * f) {
foo(f);
}

int main(int, char **) {
MyClass m;
baz1(&m);
baz2(&m);
}

Basically, in order to do that, you'd need some way to determine in foo() if baz1() or baz2() had been called. However, with MSVC in release mode, (and adding stuff into foo() to make sure it doesn't get inlined) the assembly for baz1() looks like:

jmp ?foo@@YAXPAUMyClass@@@Z ; foo

and the assembly for baz2() looks like:

jmp ?foo@@YAXPAUMyClass@@@Z ; foo

With no difference in the generated code there's no way to determine which was called. Since the resulting code is just a jump, there's no stack frame to examine and, in fact, with redundant COMDAT folding, even the function addresses would be the same.

Share this post


Link to post
Share on other sites
Quote:
Original post by Atrix256
You can always check if this == 0

The only way for "this == 0" to ever be true is to rely on undefined behavior. The function will explode before the check for virtual functions, and may evaluate to false even when the object the function was called on was null.

Especially in the case of multiple and/or virtual inheritance.

No seriously:
#include <iostream>

struct foo1 {
int a;
void f1() { std::cout << (this==0) << std::endl; }
};

struct foo2 {
int b;
void f2() { std::cout << (this==0) << std::endl; }
};

struct bar : foo1, foo2 {
int c;
void b1() { std::cout << (this==0) << std::endl; }
};

int main() {
bar* c = 0;
c->f1();
c->f2();
c->b1();
}






1
0
1
Press any key to continue . . . _


Results from both debug and release builds of a standard Win32 Console Project in MSVC2008 Professional. Remember kids: Friends don't let friends rely on undefined behavior!

[Edited by - MaulingMonkey on September 8, 2009 8:30:40 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!