This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Bogus 'pure virtual method called' abort in all g++ versions
- To: janr at molienergy dot com
- Subject: Re: Bogus 'pure virtual method called' abort in all g++ versions
- From: "James A. Bednar" <jbednar at cs dot utexas dot edu>
- Date: Tue, 19 Sep 2000 15:05:32 -0500 (CDT)
- CC: bug-gcc at gnu dot org
- References: <71B30885B657D111809D080009EEBBF30155615F@mailserv.molienergy.bc.ca>
- Reply-to: jbednar at cs dot utexas dot edu
| From: Jan Reimers <janr@molienergy.com>
| Cc: "'bug-gcc@gnu.org'" <bug-gcc@gnu.org>
| Date: Tue, 19 Sep 2000 12:54:58 -0700
|
| Your storing a reference to a temporary which gets destroyed by the time you
| call c.g(). When compiling with -Wall the compiler (2.95.2) still gave no
| warning. I think it should.
Ah, that's it, thanks! Yes, I guess I've gotten used to the compiler
warning about that when it's a problem, so it would be good if a
warning could be added. A warning would be particularly useful since
the symptoms are fairly strange -- seems like it should segfault
instead, since not only is there no object of type B anymore, there
isn't one of type A either. I wonder why other compilers don't object
either. Hmm...
Thanks,
Jim
| > -----Original Message-----
| > From: James A. Bednar [mailto:jbednar@cs.utexas.edu]
| > Sent: Tuesday, September 19, 2000 12:43 PM
| > To: bug-gcc@gnu.org
| > Subject: Bogus 'pure virtual method called' abort in all g++ versions
| >
| >
| >
| > The following code aborts with a message saying 'pure virtual method
| > called' (see output attached), even though C++ compilers on other
| > platforms do not complain, and the code looks valid to me:
| >
| > struct A {
| > virtual ~A() { }
| > virtual void f() const=0;
| > };
| >
| > strict B : public A {
| > virtual ~B() { }
| > virtual void f() const { }
| > };
| >
| > struct C {
| > const A& a;
| >
| > C(const A& a_init=B()) : a(a_init) {
| ^^^^^^
|
|
| > a.f();
| > }
| >
| > void g() const {
| > a.f();
| > }
| > };
| >
| >
| > int main(int argc, char **argv)
| > {
| > const C c;
| > c.g();
| > }
| >
| > The program runs fine under g++ if the second "a.f()" call is
| > commented out. Presumably, the type B default argument to C's
| > constructor is somehow being sliced to its base type A before that
| > call. Oddly enough, that slicing appears to happen *after* the
| > constructor completes, since the first "a.f()" call does not cause any
| > problems.
| >
| > Perhaps I'm misunderstanding some obscure part of the C++ standard
| > with respect to default arguments, but this behavior certainly *seems*
| > incorrect. The same behavior was observed in egcs 1.1.2, GCC 2.95.2,
| > and the 20000919 CVS snapshot at
| > http://www.codesourcery.com/gcc-compile.shtml.
| >
| > By the way, debugging things like this would be a lot easier if we got
| > a little more debugging information than just "pure virtual method
| > called", at least when compiled with -g :-).
| >
| > In case this code proves useful as a test case, I hereby place it into
| > the public domain for anyone to use for any purpose whatsoever.
| >
| > Jim Bednar
| >
| > --------------------------------------------------------------
| > -----------------
| > pale:~> g++ -v
| > Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.95.2/specs
| > gcc version 2.95.2 19991024 (release)
| > pale:~> cat bug16.c
| > struct A {
| > virtual ~A() { }
| > virtual void f() const=0;
| > };
| >
| > struct B : public A {
| > virtual ~B() { }
| > virtual void f() const { }
| > };
| >
| > struct C {
| > const A& a;
| >
| > C(const A& a_init=B()) : a(a_init) {
| > a.f();
| > }
| >
| > void g() const {
| > a.f();
| > }
| > };
| >
| >
| > int main(int argc, char **argv)
| > {
| > const C c;
| > c.g();
| > }
| >
| >
| > pale:~> g++ bug16.c -o bug16
| > pale:~> ./bug16
| > pure virtual method called
| > Abort (core dumped)
| > pale:~> diff -u bug16.c bug16a.c
| > --- bug16.c Tue Sep 19 14:30:11 2000
| > +++ bug16a.c Tue Sep 19 14:31:49 2000
| > @@ -16,7 +16,7 @@
| > }
| >
| > void g() const {
| > - a.f();
| > + // a.f();
| > }
| > };
| >
| > pale:~> g++ bug16a.c -o bug16a
| > pale:~> ./bug16a
| > pale:~>
| >
| >