Question

Here's my question with sample code. In the case a class function never uses instance related data or never references this, could the compiler decide this function is kind of static ?

As an example see this code (with description below) :

class Dummy
{
    public:
        Dummy()
        {
            std::cout << "Dummy()" << std::endl;
            mInstance = this;
        }
        ~Dummy()
        {
            std::cout << "~Dummy()" << std::endl;
            mInstance = nullptr;
        }

        static Dummy& instance()
        {
            std::cout << "static Dummy& instance()" << std::endl;
            return *mInstance;
        }

        void foo()
        {
            std::cout << "bar" << std::endl;
        }


    private:
        int mData;
        static Dummy* mInstance;


};

Dummy* Dummy::mInstance = nullptr;
  • At construction, my Dummy class references it's instance in a static variable called mInstance using a pointer.
  • mInstance is available through the static function instance().
  • foo() is not a static function. Hence I need and instance to call it.
  • mInstance is initialized to nullptr.

That case if my main only does :

Dummy::instance().foo();

I should get a seg fault. Because instance() would de-reference a nullptr.

Instead the program runs and the output will be :

bar

...And only this line so it does not seem to call neither the constructor nor the destructor.

Yet if my foo() function is :

        void foo()
        {
            mData = 5;
            std::cout << "bar" << std::endl;
        }

Here a seg fault occurs.

I tend to guess as foo() actually did not reference anything proper to the instance, the compiler guessed it was a static and compiled this way. But it does not seem to be logical as instance() function returns a reference to an instance and even if the foo() is static, foo() should not be callable...

As an other example, without the mData = 5 instruction, if my main is :

        Dummy& vDummy = Dummy::instance();
        std::cout << &vDummy << std::endl;
        vDummy.foo();

The output is :

        statci Dummy& instance()
        0
        bar

I don't really understand the way things are done here.... :/

Was it helpful?

Solution

You can think of member functions (non static) as functions with a hidden parameter that is a pointer to your object. So your void foo() could be considered as void foo(Dummy* d). And since you never use that pointer to Dummy, it does not matter if you pass a NULL pointer to it.

Hope this makes sense :)

For further reading about this type of undefined behaviour: When does invoking a member function on a null instance result in undefined behavior?

OTHER TIPS

The reason for this behaviour is that 'foo()' isn't virtual, so the object it's being called on is only used for type information at compile time. At runtime the fact that it's null has no effect, unless you used 'this' inside 'foo()', when you would get a nasty surprise, as you did when you tried to set a member variable, which uses 'this' implicitly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top