473,388 Members | 1,097 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

Why pA->foo() works in this code?

Hi

why this code works?

#include <iostream>

class A {
public:
void foo() {std::cout << "hi" << std::endl; };
};

void MakeA(A *pA) { pA = new A; }

int main() {
A* pA = NULL;
Make(pA);
pA->foo();
delete pA;

return 0;
}

And... why ((A*)NULL)->foo() works too?

Thanks in advance.
Jan 15 '08 #1
8 1629
Luis Angel Fernandez Fernandez wrote:
why this code works?

#include <iostream>

class A {
public:
void foo() {std::cout << "hi" << std::endl; };
};

void MakeA(A *pA) { pA = new A; }

int main() {
A* pA = NULL;
Make(pA);
pA->foo();
delete pA;

return 0;
}

And... why ((A*)NULL)->foo() works too?
The code has undefined behaviour (UB). One of the results of UB
is the appearance of being "working". Read up on UB and don't
write code like that.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jan 15 '08 #2
On Jan 15, 10:59 am, Luis Angel Fernandez Fernandez
<laff...@gmail.comwrote:
Hi

why this code works?
why shouldn't it?
>
#include <iostream>

class A {
public:
void foo() {std::cout << "hi" << std::endl; };
extra semicolon above
>
};

void MakeA(A *pA) { pA = new A; }

int main() {
A* pA = NULL;
Make(pA);
pA->foo();
delete pA;

return 0;

}

And... why ((A*)NULL)->foo() works too?
jump off a bridge: does that work too?
Modify type A by adding a member, then modify or access that member
with foo().
Do you still think you can jump off the bridge?
>
Thanks in advance.
Jan 15 '08 #3
On 15 Jan, 15:59, Luis Angel Fernandez Fernandez <laff...@gmail.com>
wrote:
* Hi
* why this code works?

class A {
* public:
* * void foo() {std::cout << "hi" << std::endl; };
};

void MakeA(A *pA) { pA = new A; }
This just sets pA and then forgets it value: you mean
void MakeA(A*& pa) { pA = new A; }
int main() {
* A* pA = NULL;
* Make(pA);
* pA->foo();
* delete pA;

* return 0;

}

* And... why ((A*)NULL)->foo() works too?

* Thanks in advance.
This came up recently, see:
http://groups.google.co.uk/group/com...427ed638?hl=en
Jan 15 '08 #4
El Tue, 15 Jan 2008 08:15:40 -0800, tragomaskhalos escribió:

Hi, again.

Thank you all for your anwsers.
>void MakeA(A *pA) { pA = new A; }

This just sets pA and then forgets it value: you mean void MakeA(A*& pa)
{ pA = new A; }
That's what we thought, but when we saw it working (or doing something
it seemed right) we were surprised.

>Â* And... why ((A*)NULL)->foo() works too?

This came up recently, see:
http://groups.google.co.uk/group/com...thread/thread/
a807522e71a60c8e/f4afa72f427ed638?hl=en
Thank you. I was searching something about that, but I couldn't find
anything.

Bye.

--
Ubuntu 7.10 (gutsy) (kernel 2.6.22-14-generic i686) GNOME 2.20.1
Intel(R) Core(TM)2 Quad CPU (2260.245 MHz) up 33 min, 2 users
HT: ZanzabornÃ*n (1457021) X.1762 # http://muxin.no-ip.org/
SK: C.D. Arrancatapinos (18088) IV.57 # Jabber: la*****@gmail.com
Jan 15 '08 #5
Salt_Peter <pj*****@yahoo.comwrites:
On Jan 15, 10:59 am, Luis Angel Fernandez Fernandez
<laff...@gmail.comwrote:
[...]
> And... why ((A*)NULL)->foo() works too?

jump off a bridge: does that work too?
There are small bridges, and there are high bridges ;-)
Modify type A by adding a member, then modify or access that member
with foo().
Do you still think you can jump off the bridge?
--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
Jan 15 '08 #6
On Jan 15, 1:40 pm, "Luis Angel Fdez. Fdez." <laff...@gmail.com>
wrote:
El Tue, 15 Jan 2008 08:15:40 -0800, tragomaskhalos escribió:

Hi, again.

Thank you all for your anwsers.
void MakeA(A *pA) { pA = new A; }
This just sets pA and then forgets it value: you mean void MakeA(A*& pa)
{ pA = new A; }

That's what we thought, but when we saw it working (or doing something
it seemed right) we were surprised.
It doesn't forget its value, the pointer is passed by value. In other
words, the pointer pA in main() is indeed pointing to a valid new
allocation upon function return. Of course, there is a syntax error in
main():
Make(pA);
should be
MakeA(pA);

as far as the following is concerned, ask yourself: is a constructor
of any kind invoked? no, hence undefined behaviour.
>
And... why ((A*)NULL)->foo() works too?
This came up recently, see:
http://groups.google.co.uk/group/com...thread/thread/
a807522e71a60c8e/f4afa72f427ed638?hl=en

Thank you. I was searching something about that, but I couldn't find
anything.

Bye.

--
Ubuntu 7.10 (gutsy) (kernel 2.6.22-14-generic i686) GNOME 2.20.1
Intel(R) Core(TM)2 Quad CPU (2260.245 MHz) up 33 min, 2 users
HT: Zanzabornín (1457021) X.1762 #http://muxin.no-ip.org/
SK: C.D. Arrancatapinos (18088) IV.57 # Jabber: laff...@gmail.com
Jan 15 '08 #7
Luis Angel Fernandez Fernandez wrote:
Hi

why this code works?

#include <iostream>

class A {
public:
void foo() {std::cout << "hi" << std::endl; };
};

void MakeA(A *pA) { pA = new A; }
From your question I think you understand that pA in main is not being
changed, that the pA in this function is a temporary and that after this
function is closed there is no way to delete the newed A.
int main() {
A* pA = NULL;
Make(pA);
pA->foo();
pA points to NULL still. Now, why does pA->foo(); work? It is undefined
behavior. However. Most compilers (if not all?) would actually convert
this to a call like:
foo( pA );

There is only one copy of the function A::foo() even if you have 100
instances of A. The hidden this pointer points to the instance of the
class, in this case NULL. Your function
void foo() {std::cout << "hi" << std::endl; };
does not attempt to dereference the this pointer (it does not try to access
any variables of the class) so for this undefined behavior you are getting
output. If you want to see different behavior for the exact same call, try
changing your class to:

class A {
public:
void foo() {std::cout << "hi" << i << std::endl; };
private:
int i;
};

and running the program and you should see a memory access violation reading
some location. That's because now the function is attempting to dereference
the this pointer, << i << becoming something like << this->i << which is
NULL plus some offset.

You can not count on undefined behavior, it is undefined. Sometimes you can
explain it however, but that doesn't mean you should count on it to always
work that way on different compilers or even the same compiler.
delete pA;

return 0;
}

And... why ((A*)NULL)->foo() works too?
Same as above. It becomes in the compiler foo( NULL );
Thanks in advance.
--
Jim Langston
ta*******@rocketmail.com
Jan 16 '08 #8
On Jan 15, 4:36 pm, Pascal Bourguignon <p...@informatimago.comwrote:
Salt_Peter <pj_h...@yahoo.comwrites:
On Jan 15, 10:59 am, Luis Angel Fernandez Fernandez
<laff...@gmail.comwrote:
[...]
And... why ((A*)NULL)->foo() works too?
jump off a bridge: does that work too?

There are small bridges, and there are high bridges ;-)
feel free to test the difference.
>
Modify type A by adding a member, then modify or access that member
with foo().
Do you still think you can jump off the bridge?

--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
Jan 16 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Abhijeet | last post by:
I was just toying around idea of deleting this from a member function. Was expecting that any acess to member variable or function after deleting sould give me dump(segmetation violation).Cause now...
5
by: DanH | last post by:
I am not a javascript person but I need a line or two of code. Hopefully one of you guys can help please. Here's my problem. I have a string called 'mystate' and I need to assign a variable...
6
by: Bryan | last post by:
I hate it when people reinvent the wheel. This is some legacy code that I believe may be causing some memory issues. I think there may be a problem in the way that the CVector class is...
11
by: Ceri Williams | last post by:
I followed the excellent MSDN article "Code Generation in the .NET Framework Using XML Schema" to build a substitute for the limited xsd.exe. My code works fine under .NET framework 1.1, but after...
16
by: Colin JN Breame | last post by:
char *pA; char *pB; pA = pB; This doesnt compile. On second thoughts, does (x) char *pA mean (a) "A pointer to 5 characters" or
8
by: Philipp Buehler | last post by:
Hello, postgresql 7.3.4 on Debian or the redhat packaged 7.3.4-8 on RHEL AS3 - same issue, so I somewhat cut out RH is playing things on me. Tested on two different PCs, too (say, one debian,...
10
by: Math | last post by:
Hello, I wonder if I can ask this particular question here... I'm writing this piece of Python Software and I'm almost done...:-) But now I want the end-user to register this software with a...
8
by: Martin Jørgensen | last post by:
Hi, "C primer plus" p.382: Suppose we have this declaration: int (*pa); int ar1; int ar2; int **p2;
0
by: Ragianand | last post by:
CREATE FUNCTION FN_APPCONSULTANTS(DOCIDPATIENTVISIT VARCHAR,ADMDATE DATE,ELS NUMBERIC) RETURNS VARCHAR LANGUAGE SQL CONTAINS SQL BEGIN ATOMIC DECLARE strAPPCONSULTANTS VARCHAR(2000);...
5
by: =?Utf-8?B?bXBhaW5l?= | last post by:
So this one is confusing as everything works but I want this warning to go away. This is what I have (within a .NET 2.0 Web Application, using VS.NET 2008 SP1): default.aspx: <%@ Page...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.