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

Started by
29 comments, last by phresnel 14 years, 7 months ago
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?
------------Anything prior to 9am should be illegal.
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.
I don't understand the question... can you perhaps give a concrete example of why you'd want to do this?
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?
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)
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?

throw table_exception("(? ???)? ? ???");

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.
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?
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.
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();}


101Press 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]

This topic is closed to new replies.

Advertisement