Topic: Pure virtual function called


Author: "John Hickin" <hickin@nortelnetworks.com>
Date: 1999/10/05
Raw View
M$ products aren't known for their ANSI conformance. VC5 is wrong to
allow this, IMHO, although I would invite you to try the code in the
debugger. Maybe it is an ill-advided optimization (turning a virtual
function call f() into a non-virtual call A::f()) but, IMHO, that is not
allowed. This raises very interesting questions for poeple who try to
optimize virtual calls into non-virtual ones.

Regards, John.

P.S.: With VC6, running in a debugger, you get a run time error.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ron Natalie <ron@sensor.com>
Date: 1999/10/01
Raw View


Zeisel Helmut wrote:
>

> Who is right according to ISO C++?
>
The code is wrong in both cases.  During construction (and destruction)
the type of the object used to resolve virtuals is the static type for
which the constructor is being executed.  In A::A, A::f is going to be
called (both directly and in the case of the g()->f() chain).  Since
there is no body for f(), the call is invalid.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: zeisel@my-deja.com
Date: 1999/10/01
Raw View
In article <37F5076F.358E6949@sensor.com>,
  Ron Natalie <ron@sensor.com> wrote:
>
>
> Zeisel Helmut wrote:
> >
>
> > Who is right according to ISO C++?
> >
> The code is wrong in both cases.  During construction (and destruction)
> the type of the object used to resolve virtuals is the static type for
> which the constructor is being executed.  In A::A, A::f is going to be
> called (both directly and in the case of the g()->f() chain).  Since
> there is no body for f(), the call is invalid.

Please observe that although f() is pure virtual,
I defined a body for A::f().
So at least in theory,
one could call A::f() during the construction of A.

Helmut



Sent via Deja.com http://www.deja.com/
Before you buy.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: zeisel@vai.co.at (Zeisel Helmut)
Date: 1999/10/01
Raw View
The following program runs fine under MS VC++ 5.0,
put gives a "Pure virtual function called"
on Sun, C++ 4.1.

Calling g() from the constructor of A()
(i.e., uncommenting the "g()" line)
gives also a "pure virtual function called" with MS VC++ 5.0.

Who is right according to ISO C++?

If VC++ were right,
why is it allowed to call a pure virtual function
directly from the constructor,
but not indirectly via another function call?

Helmut

-------------------------

#include <iostream.h>
class A
{
public:
  virtual void f() = 0;
  void g() {f();}
  A()
  {
     f();
    // g();
  }
};
void A::f() {cout << "A::f()" << endl;}
class B: public A
{
public:
    void f() {}
};
int main()
{
    B b;
    return 0;
}



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/10/01
Raw View
zeisel@my-deja.com writes:

>In article <37F5076F.358E6949@sensor.com>,
>  Ron Natalie <ron@sensor.com> wrote:
>>
>>
>> Zeisel Helmut wrote:
>> >
>>
>> > Who is right according to ISO C++?
>> >
>> The code is wrong in both cases.  During construction (and destruction)
>> the type of the object used to resolve virtuals is the static type for
>> which the constructor is being executed.  In A::A, A::f is going to be
>> called (both directly and in the case of the g()->f() chain).  Since
>> there is no body for f(), the call is invalid.

>Please observe that although f() is pure virtual,
>I defined a body for A::f().
>So at least in theory,
>one could call A::f() during the construction of A.

There is a subtle point about calling pure virtual functions
that have been defined (have a body).

A pure virtual function can NEVER be called via the virtual
function mechanism, even when it has been defined.

The only way to call a pure virtual function is by explicit
qualification. Example:

struct base {
    virtual int base::f() = 0;
    base();
};
// base::base() { f(); }   // always an error
base::base() { base::f(); }   // OK if base::f is defined

If you like to think in implementation terms, the vtable for class
base will not have pointer to base::f, so you can't call base::f
via the virtual mechanism. Even when you write "f()" in a member
of class base, the meaning is "this->f()", and so the function
won't be called. Only when you write "base::f()" do you bypass
the virtual mechanism and get to the pure virtual function.

In typical implementations, the vtable slot for a pure virtual
function contains a pointer to a function that prints a message
about attempting to call a pure virtual function. The standard
doesn't require that behavior; it just says the results of
attempting to call a pure virtual function are undefined.

--
Steve Clamage, stephen.clamage@sun.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andy Philpotts <AndyPhi@reciprocal.com>
Date: 1999/10/02
Raw View
In article <37F5076F.358E6949@sensor.com>, ron@sensor.com says...
>
>
>
> Zeisel Helmut wrote:
> >
>
> > Who is right according to ISO C++?
> >
> The code is wrong in both cases.  During construction (and destruction)
> the type of the object used to resolve virtuals is the static type for
> which the constructor is being executed.  In A::A, A::f is going to be
> called (both directly and in the case of the g()->f() chain).  Since
> there is no body for f(), the call is invalid.
>

So "void A::f() {cout << "A::f()" << endl;}" does not count as a body
because is comes after the class, surely this is a wrong interpretation.
Is this not something to do with the fact that it is OK to define an
implementation for a pure-virtual, but it may only be called in a non-
virtual fashion???

>
>
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]
>
>
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]