开发者

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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜