4

Possible Duplicate:
What will happen when I call a member function on a NULL object pointer?

class A {
  public:
    void foo() { cout << "Work";}
    void bar() { this->foo(); }//new edit, works too!
};

class B {
  private:
    A *a; //never initialized
  public:
    A& getA() {
      return *a;
    }
};

void SomeFunction() {
    B *b = new B();
    B& bRef = *b;
    bRef.getA().bar();//edited
    delete b;
}

I called SomeFunction() without initializing "a" and it still prints "Work" correctly. I don't understand why, it should have bailed out with segmentation fault!

Community
  • 1
  • 1
Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
  • 7
    that is the beauty(read: scary part) of undefined behavior – AndersK Oct 18 '12 at 07:34
  • I posted this as an answer to a question. And then noticed that its WRONG! Yet when I ran this program it printed the correct answer. Baffled I posted a question. – Aniket Inge Oct 18 '12 at 07:36

3 Answers3

10

This is undefined behavior, but it will work on most compilers, as foo is not virtual and it doesn't use the this pointer.

Henrik
  • 23,186
  • 6
  • 42
  • 92
  • used "this" and its still working! – Aniket Inge Oct 18 '12 at 08:02
  • 1
    @PrototypeStark - no, you're not using this. It's not need to call foo. Therfore it's also not need to call bar. – Henrik Oct 18 '12 at 08:07
  • @PrototypeStark See my answer for why that doesn't use `this`. – Kaz Dragon Oct 18 '12 at 09:28
  • @Henrik, I know if its not needed to call "foo" then I don't need this to call bar. BUT I am being clear when I said, INTERNALLY I am calling foo using "this" pointer. BUT since you said I am not using "this" pointer. I corrected and tested it out. – Aniket Inge Oct 18 '12 at 09:30
5

Remember classes are just a construct of C++. When compiled, all class methods are just static methods that accept a hidden this parameter.

Given that your foo() method never references any data members, it never needs to use it, and so runs fine despite the uninitialised value of this.

GazTheDestroyer
  • 20,722
  • 9
  • 70
  • 103
  • educational. But scary none-the-less. – Aniket Inge Oct 18 '12 at 07:46
  • 1
    out of the three answers, I selected your's because you clearly mentioned that foo() still accepts "this" pointer. My code-edit proves that it does. Unlike Henrik's ansswer, in which he said "it works because its not virtual and it doesn't use this pointer" – Aniket Inge Oct 18 '12 at 08:08
  • -1 This answer does not mention the most important point, which is that according to the language spec the behaviour of this code is undefined and may therefore vary depending on the compiler. – Chris Dickson Oct 18 '12 at 08:12
3

Semantically,

o.f(args)

is the same as

f(o, args)

So you could consider the function you are calling (A::foo()) to be equivalent to :

void A_foo(A* pthis)
{
    cout << "Work";
}

As you can see, pthis is never dereferenced, so no invalid memory access occurs. Even if you type this->foo(), it's exactly the same invocation, and this does not need to be dereferenced.

At least, that's one common way of a compiler implementing it. It's undefined as to precisely what might happen, so running the code on the Death Station 9000 might beam a kitten into space instead. Think of the kittens!

Kaz Dragon
  • 6,681
  • 2
  • 36
  • 45