a class function with if(this==NULL) test got compiled?
I saw this code snippet during our lab and it actually compiles in MSVC2008 and G++.
void LinkList< class T >::Insert(T n)
{
if (this == NULL)
// some code here
}
As far as I know the this
must not be null since you cannot call a class functions in c++ if it wasn't instantiated. Is this a valid code?开发者_如何学Go if so what's the reason behind and where it can be useful?
since you cannot call a class functions in c++ if it wasn't instantiated
The thing is, you can, but it leads to undefined behavior.
Such a check should probably be an assert, though such code isn't guaranteed to actually work by the standard. (If this
is null, you're already in undefined behavior land.)
The reason it's "useful" is to detect using an object after it's been deleted, or if it was never created:
template <typename T> // I hate this function
void safe_delete(T*& pPtr)
{
delete pPtr;
pPtr = 0;
}
T* p = new T;
safe_delete(p);
p->foo(); // this is null, and we've entered undefined behavior
Within foo
, you could assert, "hey, we messed up :/".
In my opinion such use is indicative of bad design. You shouldn't have a pointer lying around that might possibly get invoked again. The last thing you do with a pointer is delete
it; if it's still around after that, change your code so it's not.
This is the type of problem it is trying to 'solve' :
class A
{
public:
void test()
{
if(this == NULL)
{
std::cout<<"This is NULL\n";
}
}
};
int main() {
A* p = NULL;
p->test();
return 0;
}
However, note that calling p->test()
invokes undefined behavior, so this
may or may not be NULL. My guess is that somebody was is in real hurry and chose to do this instead solving the actual problem. Don't use it, it will never work reliably or predictably. Regarding why it compiles, this
is just a const pointer and comparing a pointer to NULL
is syntactically valid.
if class variable is not instantiated... It's behavior is undefined... So compiler will not give you error... But behavior of the function is undefined... It can run even perfectly fine if before if (this == NULL)
statement no any class member is used...
Because this
is just a pointer, the code is valid -- this means the comparison is valid. Whether the code in the conditional block is executed or not is another issue.
According to the C++ standard, it's undefined behavior. However, a typical C++ implementation will treat a non-virtual member function
void A::func(int arg);
like the C-style function
void A_func(A* this, int arg);
And just like any pointer argument, it's OK for "this" to be NULL as long as you don't dereference the memory. So, if you write:
#include <iostream>
class A
{
public:
void test();
};
void A::test()
{
std::cout << "This function could have been static." << std::endl;
}
int main()
{
((A*) NULL)->test();
return 0;
}
It will run just fine (at least under MSVC and G++).
However, this gives a segmentation fault:
#include <iostream>
class A
{
public:
void test();
private:
int _n;
};
void A::test()
{
_n = 42;
}
int main()
{
((A*) NULL)->test();
return 0;
}
The if (this == NULL) check is an attempt to prevent a null pointer dereference from crashing the program.
But to conform to the standard, it's better to do the test from the outside.
if (pList != NULL)
{
pList->Insert(value);
}
精彩评论