-1

I want to understand how following program works.

class A{
    public:
    virtual void fun();
};

void A:: fun()
{
    cout << "fun() called";
}

int main() {

    A *ptr_a;
    ptr_a->fun();
    return 0;
}

It doesn't prints "fun() called". I tried to find a reasonable explanation for this but I couldn't. If I remove virtual from the declaration then it works fine. Also there is no runtime error.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 5
    *Undefined behavior* is what is happening. You don't have any object that `ptr_a` is pointing to – UnholySheep Jan 03 '19 at 14:41
  • 2
    related/dupe: https://stackoverflow.com/questions/2533476/what-will-happen-when-i-call-a-member-function-on-a-null-object-pointer – NathanOliver Jan 03 '19 at 14:42
  • 1
    Since your function uses no member variables of the class it will usually seem to work properly calling it through a bogus or null pointer, but it's still wrong and will someday come back to haunt you. – Retired Ninja Jan 03 '19 at 14:44
  • If i make the function pure virtual, then the compiler should throw error as I am calling pure virtual function ? Isn't it? – despicable_me Jan 03 '19 at 15:15

1 Answers1

3

There is no reason to expect this to work, and no reason to expect it not to work.

You're calling a function on an object that doesn't exist, through an uninitialised and invalid pointer.

Anything can happen.

Anything.

In practice you're not going to see great virtual dispatch results since these rely on data stored within the object that doesn't exist, whereas a normal function call is simpler and can "just happen" without needing to really dereference the pointer.

But that's besides the point really, because compilers are complicated and all intended meaning (whatever that is, in a program with undefined behaviour!) can easily be lost from your code in the process of translation and optimisation.

A language that cares a little less about "pay for what I don't use" could make this a hard error, but that's not how C++ works.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Notably, this _is_ a warning if you ask the compiler to warn you: https://godbolt.org/z/nU2BzE – Max Langhof Jan 03 '19 at 15:43
  • My point is that if the fun() is getting executed then why it not printing & if it is not getting executed then why calling the fun() is not throwing any compile/runtime error? – despicable_me Jan 03 '19 at 15:44
  • 1
    @despicable_me Refer to my final paragraph. C++ makes you bear the responsibility of mistakes such as this. There are many reasons. Research "undefined behaviour" for more on this topic. – Lightness Races in Orbit Jan 03 '19 at 15:44
  • "hard" mean "deterministic", now? – curiousguy Jan 03 '19 at 22:25
  • @curiousguy "hard" means "reliably breaks the build every time". So a bit yes but mostly the notion of program rejection. – Lightness Races in Orbit Jan 03 '19 at 23:51
  • @LightnessRacesinOrbit Funny: I use "hard error" for "don't try again, please fix the problem" and "soft error" for "you may try again later". OTOH an error that randomly appears (such errors will always exist as long as there is non-determinism in a program) should be investigated and fixed; one shouldn't re-try running a program until the symptoms of UB goes away (or gets so subtle nobody can notice it). – curiousguy Jan 04 '19 at 00:23
  • 1
    @curiousguy Yeah I don't know what it's "supposed" to mean but that's how I meant it anyway ^_^ – Lightness Races in Orbit Jan 04 '19 at 11:13