PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Why pA->foo() works in this code?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Why pA->foo() works in this code?

Réponse
 
LinkBack Outils de la discussion
Vieux 15/01/2008, 15h59   #1
Luis Angel Fernandez Fernandez
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut 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.
  Réponse avec citation
Vieux 15/01/2008, 16h02   #2
Victor Bazarov
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

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


  Réponse avec citation
Vieux 15/01/2008, 16h11   #3
Salt_Peter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

On Jan 15, 10:59 am, Luis Angel Fernandez Fernandez
<laff...@gmail.com> wrote:
> 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.


  Réponse avec citation
Vieux 15/01/2008, 16h15   #4
tragomaskhalos
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

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
  Réponse avec citation
Vieux 15/01/2008, 18h40   #5
Luis Angel Fdez. Fdez.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

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: laffdez@gmail.com
  Réponse avec citation
Vieux 15/01/2008, 21h34   #6
Salt_Peter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

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


  Réponse avec citation
Vieux 15/01/2008, 21h36   #7
Pascal Bourguignon
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

Salt_Peter <pj_hern@yahoo.com> writes:

> On Jan 15, 10:59 am, Luis Angel Fernandez Fernandez
> <laff...@gmail.com> wrote:
> [...]
>> 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
  Réponse avec citation
Vieux 16/01/2008, 00h31   #8
Jim Langston
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

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
tazmaster@rocketmail.com


  Réponse avec citation
Vieux 16/01/2008, 01h34   #9
Salt_Peter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Why pA->foo() works in this code?

On Jan 15, 4:36 pm, Pascal Bourguignon <p...@informatimago.com> wrote:
> Salt_Peter <pj_h...@yahoo.com> writes:
> > On Jan 15, 10:59 am, Luis Angel Fernandez Fernandez
> > <laff...@gmail.com> wrote:
> > [...]
> >> 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


  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 02h10.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,16249 seconds with 17 queries