Pointer to Class prb

V

Venkatesh

Hi All,

I tried the following code and it seems to work. I am really confused as to
how this is possible. Can someone please throw some light?

#include<iostream>
using namespace std;

class Y
{
public :
void foo()
{
cout << "Hello World"<< endl;

}
};

main ()
{
Y *ptr = NULL;
ptr->foo();
}

Thanks in advance.

Venky
 
J

John Harrison

Venkatesh said:
Hi All,

I tried the following code and it seems to work. I am really confused as to
how this is possible. Can someone please throw some light?

#include<iostream>
using namespace std;

class Y
{
public :
void foo()
{
cout << "Hello World"<< endl;

}
};

main ()
{
Y *ptr = NULL;
ptr->foo();
}

Thanks in advance.

Venky

This code is dereferences a NULL pointer, therefore the program is wrong.

Now here is one of the secrets of C++. Almost always when a program does
something wrong like this, the C++ standard does NOT says that the program
must crash, its does NOT say that the program must produce an error message,
what it says is that the program has UNDEFINED BEHAVIOUR.

Undefined behaviour means exactly what it says, anything could happen,
including the program working. If you ran this program on a different
computer, or with a different compiler or even on a different day of the
week you might get different behaviour. This is what makes programming C++
hard.

John
 
J

Jeff Schwab

Venkatesh said:
Hi All,

I tried the following code and it seems to work. I am really confused as to
how this is possible. Can someone please throw some light?
main ()
{
Y *ptr = NULL;
ptr->foo();
}

This is called "dereferencing null." It's generally considered a bad
thing to do. Here's what I believe you want:

int main( )
{
Y y;
y.foo( );
}

If you really want a pointer, try this:

int main( )
{
Y y;
Y* p = &y;
p->foo( );
}
 
R

Rob Williscroft

Venkatesh wrote in in comp.lang.c++:
Hi All,

I tried the following code and it seems to work. I am really confused
as to how this is possible. Can someone please throw some light?

#include<iostream>
using namespace std;

class Y
{
public :
void foo()
{
cout << "Hello World"<< endl;

}
};

main ()
{
Y *ptr = NULL;
ptr->foo();
}

That the code "works", is one possible result of Undefined Behaviour.

Once you write ptr->something, when ptr is null, you are derefrencing
a NULL pointer, the C++ Standard no longer say's what behaviour your
code exhibits.

It "works", it "doesn't work", your computer grows legs and runs of
with the milkman, all are acceptable.

If your next question is "well why does it work on my implementation",
then probably (just guessing) ptr isn't need to actually call Y::foo(),
since it isn't virtual. So all that happens is ptr is passed to y::foo()
as the 'this' pointer and since Y::foo() doesn't reference 'this' in any
way you Get Away With It(tm).

FYI: main() returns int and only int, also all function's in C++
*must* have a return type, the K&R implicit int has *never* been C++.

HTH.

Rob.
 
J

Jeff Schwab

Jeff said:
This is called "dereferencing null." It's generally considered a bad
thing to do.

Sorry, I mis-read the question; you want to know why it *does* work. As
John and Rob already have mentioned, it's not guaranteed not to work.
Since the member function foo() in this case does not use its "this"
pointer for anything, this code is likely to work much of the time.
(Not that it's a good idea, y'unnastand.)
 
R

raj

Hi All,

I tried the following code and it seems to work. I am really confused as to
how this is possible. Can someone please throw some light?

#include<iostream>
using namespace std;

class Y
{
public :
void foo()
{
cout << "Hello World"<< endl;

}
};

main ()
{
Y *ptr = NULL;
ptr->foo();
}

c++ standard states that above code will lead to undefined behavior.
But most compilers will not crash untill you access a member variable
within the function.

If you try to modify a member variable of Y in this function, it would
crash on most platforms. Also if foo is declared virtual it would
crash while trying to find the virtual table of the null pointer.
Again this is not guaranteed, it is all undefined behavior.

Raj
 
J

Jerry Coffin

Hi All,

I tried the following code and it seems to work. I am really confused as to
how this is possible. Can someone please throw some light?

You're derefencing a null pointer, which is undefined behavior.
Undefined behavior can do anything, including seeming to work.
 
B

Bill Seurer

Venkatesh said:
class Y
{
public :
void foo()
{
cout << "Hello World"<< endl;

}
};

main ()
{
Y *ptr = NULL;
ptr->foo();
}


First off what Jerry Coffin said is true; you're just lucky that it worked.

As for why it works this is *probably* what happened. Using a pointer
to call a member function really didn't deference the pointer but
instead the function was called with the pointer as a hidden parameter
that inside foo becomes the this pointer. So the call "ptr->foo()"
probably got translated into something like "Y_foo(ptr)". Inside foo
the value of "this" was null but you never used it for anything and so
no problems.

And thus your program seems to work.

Try adding this code to foo:

if (this == 0)
cout << "Uh oh, this was null! I'm lucky the compiler doesn't slap
me or something" << endl;
 
J

JKop

Venkatesh posted:
Hi All,

I tried the following code and it seems to work. I am really confused
as to how this is possible. Can someone please throw some light?

#include<iostream>
using namespace std;

class Y
{
public :
void foo()
{
cout << "Hello World"<< endl;

}
};

main ()
{
Y *ptr = NULL;
ptr->foo();
}

Thanks in advance.

Venky


You must realize that "foo" is just like any other function. It is in memory
and it has an address in memory. It may be something like this:

void foo(MyClass* this)
{

cout << "Hello World"<< endl;
}


When you declare that "ptr" pointer and then use it call "foo", you are
calling the "foo" function as so:

foo(AnyNumber); //You didn't intialize "ptr" so it can contain ANY value,
although most likely 0.

So now when "foo" is called, it _does_ work because it doesn't even _look_
at the bogus pointer value. But...

void foo(MyClass* this)
{
cout << "Hello World"<< endl;

this.memberVariable = 5;
}


This most certainly will crash... I hope is does in anyway if you're running
an in-any-way-decent Operating System.


Just to throw it in there: "foo" should be declared "static".


That said, and as about 20,000 peole have said already, what you're doing
is...



undefined




-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top