views:

243

answers:

6

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;
}
+12  A: 

C++ allows you to use uninitialised pointers.

It's a "feature" of the language, and one of the reasons why it's 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.

RichieHindle
A: 

I suspect that ptr->func2() is optimised away as it always returns true. But as Richie says, the use of the pointer is fine in this case as you;re not touching any instance data (a) and as such there is nothing to crash into.

Preet Sangha
It cannot be optimised away, because there is more code depending on it (if statement).
Frank Bollack
It *can* be optimized away. An optimizer may assume that any code path that would result in undefined behavior at runtime is unreachable. That code path can therefore be removed, backwards from the undefined behavior to the last branch. As a result, a program that must produce UB independent of the input might be optimized to `int main() { }`
MSalters
A: 

Its not working. Its just by luck that your application is not crashing where your expecting it to crash. Its not a feature but a side-effect of the compiler which is allowing the function call to seem to work.

Andrew Keith
Not true. `func2` doesn't use its `this` pointer, so it will never crash.
RichieHindle
Not sure why this was down-voted. One could imagine evil (or perhaps helpful) compiler-writers that would indeed make it crash (after all it can be statically determined that the pointer is uninitialized, and compilers do warn about this). So this "never" of RichieHindle is incorrect (perhaps compilers are not at this level, yet). I just wouldn't call it "luck" that programs don't crash right away if code is wrong.
UncleBens
my thinking was that even though temp->func2() will resolve to func2(temp), its still not correct. Interesting note, if you run AppVerifier in windows XP with that code, it will crash on temp->func2().
Andrew Keith
+6  A: 

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.

sharptooth
+2  A: 

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.

MSalters
In Soviet Russia, unitialized pointer dereferences *you*.
Dan Moulding
A: 

You can call the methods using uninitialised pointers. It will work either ptr->func1(); or int crashere=ptr->func1();//

Sachin Chourasiya