This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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;
  };
  
  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();
  }

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:~> 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]