Why am I able to make a function call using an invalid class pointer

In below code snippet, although pointer is not initialized the call is still made successfully

temp *ptr;
ptr->func2();

Is it due to C++ language property, or it is VC++6 compiler which is foul playing?

class temp {
public:
    temp():a(9){}
    int& func1()
    {
        return a;
    }
    bool func2(int arg)
    {
        if(arg%2==0)
            return true;
        return false;
    }
    int a;
};

int main(int argc, char **argv)
{
    temp *ptr;
    int a;
    cin>>a;
    if(ptr->func2(a))
    {
        cout<<"Good poniner"<<endl;
    }
    ptr->func1(); // Does not crash here
    int crashere=ptr->func1();// But does crash here 
    return 0;
}

Solution 1:

The C++ compiler doesn't prevent you from using uninitialised pointers, and although the results are undefined, it's normal for compilers in the real world to generate code that ignores the fact that the pointer is uninitialised.

It's one of the reasons why C++ is both fast and (comparatively) dangerous relative to some other languages.

The reason your call to func2 succeeds is that it doesn't touch its this pointer. The pointer value is never used, so it can't cause a problem. In func1 you do use the this pointer (to access a member variable), which is why that one crashes.

Solution 2:

This is entirely compiler-dependent and undefined behaviour according to the standard. You shouldn't rely on this.

Call to func2() succeeds because the exact method to call is known at compile time (the call is not virtual) and the method itself doesn't dereference this pointer. So invalid this is okay.

ptr->func1(); // This works

because the compiler is instructed to return the reference to the class member. To do so it simply adds the offset of the member to the invalid value of this pointer and that produces yet another invalid pointer (reference, which is almost the same).

int crashere=ptr->func1();// Crashes here

because now the compiler is instructed to retrieve the value via that invalid reference and this crashed the program.

Solution 3:

C++ has the notion of Undefined Behavior. Using an uninitialized pointer is a common example of such Undefined Behavior. For performance reasons, the C++ standard places no restrictions whatsoever on the possible outcome. That is to say, formatting the harddisk is perfectly acceptable.