Solved

pure virtual method called

Posted on 2006-07-05
17
2,159 Views
Last Modified: 2013-11-15
It is a multi-threaded daemon on a Linux box (GCC). In 1 out of 10 start-ups, it aborts with a "pure virtual method called" error. It is not bombing out during static initialisation. It occurs in main(), but there are several threads on the go or initialising at the time. Alas, it only happens in the release build.

The only thing I can think that would cause a PVM call would be if a base constructor called a base function, which called a PVM, and I'm sniffing down that track.

i.e.
--------8<--------
struct base
{
      base() {init();} // Ctor calls a function, which calls a PVM
      void init() {f();} // Calls a PVM
      virtual void f() = 0;
};

struct derived : public base {virtual void f(){}};

int main()
{
      Derived d;
}
--------8<--------

Are there any other circumstances the panel can think of, which would result in a PVM call?
0
Comment
Question by:rstaveley
  • 8
  • 4
  • 3
  • +1
17 Comments
 
LVL 5

Expert Comment

by:bastibartel
ID: 17041281
Hi there,

Upon construction of d your code exectues:

base::base()
   base::init()
      base::f()     // derived hasn't been constructed yet. check out the vtable in the debugger in base::init()

If you call f() after derived::derived() has been entered it works.

//---- snip -------------------------

struct base
{
     base()
     {
           //** too early to call derived::f()
           /**  init()
     }
     void init()
     {
          f();
     }
     virtual void f() = 0;
};

struct derived : public base
{
    derived()
    {
         init();  // now it works
    }
    virtual void f(){}

};

int main()
{
     Derived d;
}
0
 
LVL 17

Author Comment

by:rstaveley
ID: 17041328
Yes, bastibartel, that was supposed to be an illustration of the only way I know to cause a a "pure virtual method called" error. I wasn't looking for a way to fix the illustration :-D

My question is:

> Are there any *other* circumstances the panel can think of, which would result in a PVM call
0
 
LVL 30

Expert Comment

by:Axter
ID: 17041330
Hi rstaveley,
bastibartel is absolutely correct.
Your base class should avoid calling virtual functions in its constructor and in its destructor.


David Maisonave (Axter)
Cheers!
0
 
LVL 17

Author Comment

by:rstaveley
ID: 17041337
Et tu, David?

My question is:

> Are there any *other* circumstances the panel can think of, which would result in a PVM call
0
 
LVL 30

Accepted Solution

by:
Axter earned 150 total points
ID: 17041338
rstaveley,
> > Are there any *other* circumstances the panel can think of, which
> would result in a PVM call
Calling a virtual function from the base destructor.

David Maisonave (Axter)
0
 
LVL 17

Author Comment

by:rstaveley
ID: 17041340
...though the destructor call is a good point :-)
0
 
LVL 17

Author Comment

by:rstaveley
ID: 17041346
Damn there's some fast posting going on!
0
 
LVL 30

Expert Comment

by:Axter
ID: 17041355
Sorry rstaveley.
When I posted my first two comments, I didn't pay attention to the name of the questioner.
Otherwise, I would have read the question differently.

David Maisonave (Axter)
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 5

Assisted Solution

by:bastibartel
bastibartel earned 100 total points
ID: 17041375
lol - I am sorry, rstaveley.
Oh noooo - not you again Axter ;-)

0
 
LVL 17

Author Comment

by:rstaveley
ID: 17041847
Oh crumbs... I should be shot. I just spotted this in a constructor complete with my comment:

>      // This class is self-registering. Not cool? Shouldn't be IMHO.
>      handler.Add(this);      

That definitely wasn't a clever thing to do. Let's keep this as our secret in the privacy of the...erm Internet. I think I'll go off and apply for a managerial job %-}

The moral of the story is: never think you can get away with passing a reference/pointer to a base class, but especially don't do it in an MT application.
0
 
LVL 30

Expert Comment

by:Axter
ID: 17042190
>>Oh noooo - not you again Axter ;-)

Actually, this is my usual hang out.
I rarely post in the other topic areas.
0
 
LVL 5

Expert Comment

by:bastibartel
ID: 17042290
What's your local time - maybe we can co-exist in temporally separated universes. It's 3pm here.

Have a good day :)
Sebastian
0
 
LVL 17

Author Comment

by:rstaveley
ID: 17042514
Sebastian, if you've had your nose bloodied by David in another question, take my word for it that it is almost certainly because he has a deep affection for his subject, and the struggle is much more likely to have been for truth than personal rivalry.

Best wishes and respect to you both

    Rob
0
 
LVL 4

Expert Comment

by:havman56
ID: 17048780
This is for info .
need clarification why linker error

when i compiled the above code i am getting linker error in vc6 (lnk 2001) when i call PVM directly in ctor . but where as PVM called via interface in ctor crashes as ur program .

when u call PVM in base class constructor then u need to provide implementation


class Base
{
public:
      Base();
      virtual ~Base();
      void init();
      virtual void func()=0;
      
};

class Derived :public Base
{
public:
      Derived();
      virtual ~Derived();
      virtual void func();
};

Derived d;

// this crashes ctor is calling interface which in turn calls PVM . crashes same as ur problem
Base::Base() { init(); }
void Base::init(){func(); }

// Gives linker error . bit confused
 Base::Base(){ func(); }
0
 
LVL 17

Author Comment

by:rstaveley
ID: 17049090
// Gives linker error . bit confused
 Base::Base(){ func(); }

Oddly enough, it is quite correctly a linker error and not a compiler error. It expects a *default PVF* to have been defined for void Base::func() = 0.

Add this to your code and you avoid the linker error:
--------8<--------
/* A PVF default definition!! Yes you *can* define a function body for a pure virtual function */
void Base::func()
{
}
--------8<--------

Default PVFs have their uses.
0
 
LVL 4

Expert Comment

by:havman56
ID: 17050600
my question is ctor-->initi-->func() why no linker error ?

but ctor-->func() linker error  why

0
 
LVL 17

Author Comment

by:rstaveley
ID: 17050692
The first makes a dynamic call, using the virtual method table. The second implicitly makes a static call.

As I said in your question, it would be better if the compiler warned you that it was assuming a static call.

When you write...

    Base::Base(){ func(); }

...the compiler interprets it as a static call, because you are still in the constructor - i.e.

    Base::Base(){ Base::func(); }

A static call does not use the virtual method table.

When you write....

   void Base::init(){func(); }

...the compiler interprets it as a dynamic call and looks for the function pointer in the virtual method table.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

How to update Firmware and Bios in Dell Equalogic PS6000 Arrays and Hard Disks firmware update.
VM backup deduplication is a method of reducing the amount of storage space needed to save VM backups. In most organizations, VMs contain many duplicate copies of data, such as VMs deployed from the same template, VMs with the same OS, or VMs that h…
This tutorial will walk an individual through the steps necessary to install and configure the Windows Server Backup Utility. Directly connect an external storage device such as a USB drive, or CD\DVD burner: If the device is a USB drive, ensure i…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now