开发者

C++ strange behaviour

开发者 https://www.devze.com 2023-04-08 10:23 出处:网络
Please check this code.. class ex { int i; public: ex(int ii = 0):i(ii){} ~ex(){cout<<\"dest\"<<endl;}

Please check this code..

class ex
{
     int i;
     public:
     ex(int ii = 0):i(ii){}
      ~ex(){cout<<"dest"<<endl;}
     void show()
     {
        cout<<"show fun called"<开发者_C百科<endl;
     }
};
int main(int argc , char *argv[])
{
    ex *ob = NULL;
     ob->show();
       return 0;
}

what happens when we call show method.

Thanks..


ex *ob = NULL;
ob->show();

You're dereferencing a null pointer which causes undefined behaviour. This is bad.

If it's not clear where the dereference is then understand that the -> operator translates to (*ob).show().


It is undefined behavior.

That being said, on most compilers, you will be able to call methods on null pointers as long as

1) they don't access members.

2) they are not virtual.

Most compilers will translate

ob->show()

into

call ob::show

which is a valid method present in the application space. Since you're not accessing members, there's no reason for a crash.


Calling the show method on the object pointed by a null pointer is classified as "Undefined Behavior" and it means that whatever happens you cannot tell that C++ is wrong because the mistake in on your side.

Undefined behavior means that the compiler writers do not need to care about the consequences of your bad programming... so they are free to just ignore those cases. Often undefined behavior is thought to mean "crash" but this is quite far from truth. Executing code with undefined behavior may crash, may do nothing, may apparently do nothing and make your program to crash one million instructions later in a perfectly fine place or it may even running apparently fine and without crashes at all but silently corrupting your data.

One main assumption of the C++ language is that the programmers make no mistake. In other languages this is not true and you get "runtime error angels" that will check and stop your program when you made a mistake... in C++ instead those checks are considered too expensive and therefore instead of "runtime error angels" you get "undefined behavior daemons" that in case of an error will have fun of you.

This, added to the high complexity of C++, is the reason for which I think that C++ is a very bad choice for beginners (beginners make a lot of mistakes) and make impossible to learn C++ by experimentation (because consequences of errors are non deterministic).

In your specific case, given that compiler writers are lazy (not a bad quality for a programmer) I'd guess that on x86 architectures the code wouldn't probably do any damage and it will probably execute as if the pointer was to a valid object. This is of course just speculation as it depends on the compiler, the hardware and the compiler options. Probably there are out there good compilers that have a compiling debug option that will generate code that crashes instead.


The behaviour is undefined. How the program will actually behave is implementation-dependent. I expect that most implementations try to execute the code without checking the pointer. So your initial example should run smoothly since it does not reference any local member of the class.

It is interesting to check what the following code does:

class ex
{
    int i;
    public:
    ex(int ii = 0):i(ii){}
    ~ex(){cout<<"dest"<<endl;}
    virtual void show()
    {
        cout<<"show fun called"<<endl;
    }
};

int main(int argc , char *argv[])
{
    ex *ob = NULL;
    ob->show();
    return 0;
}

If the method is virtual maybe the runtime needs to access some local data of the object, leading to a null pointer or bad address exception.

EDIT

I tested the following slightly modified example with GCC on cygwin:

#include <iostream>

using namespace std;

class ex
{
    int i;
    public:
    ex(int ii = 0):i(ii){}
    ~ex(){cout<<"dest"<<endl;}

    void show()
    {
        cout<<"show fun called"<<endl;
    }

    virtual void vshow()
    {
        cout<<"vshow fun called"<<endl;
    }
};

int main(int argc , char *argv[])
{
    ex *ob = NULL;
    ob->show();
    ob->vshow();
    return 0;
}

and, in fact, the output is:

show fun called
Segmentation fault (Core dumped)
0

精彩评论

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

关注公众号