Connecting Tech Pros Worldwide Help | Site Map

Microsoft runtime error R6025 Pure Virtual Function Call: a technicalreport

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 19th, 2005, 05:42 PM
Dario
Guest
 
Posts: n/a
Default Microsoft runtime error R6025 Pure Virtual Function Call: a technicalreport

This is a technical C++ post regarding the
Microsoft runtime error R6025 Pure Virtual Function Call
that sometime occurs in programs compiled with
Microsoft Visual C++ 6.0.

Please consider the following simple illegal C++ program:

class Listener {
public:
virtual void onEvent(int n) = 0;
};
class A : public Listener {
public:
Listener * listener;
int val;
explicit A(int n) {listener = this; val = n;}
virtual ~A() {}
virtual void run() {listener->onEvent(val);}
};
int main() {
A(42).run();
return 0;
}

This program is illegal because in the main() function
there is a call to A constructor but A cannot be constructed
because it does not declare the onEvent function.

When you try to compile it using g++
you correctly obtaing the following error:
virtual.cpp: In function `int main ()':
virtual.cpp:14: cannot allocate an object of type `A'
virtual.cpp:14: since the following virtual functions are abstract:
virtual.cpp:3: void Listener::onEvent (int)

But, surprise!, when you try to compile it using
the Microsoft C++ 6.0 compiler you have no error.
Only when you execute it you will obtain the infamous
Microsoft runtime error R6025 Pure Virtual Function Call.

If your application sometime suffers of R6025 error
there are two manners to discover the problem:
<1> Try to compile the program using an
alternative correct c++ compiler (like g++),
-or-
<2> Make a code inspection on the program
and try to figure out all code containg the pattern:
className(someParam).methodInvocation(otherParam)
and substitute it with:
className xxx(someParam);
xxx.methodInvocation(otherParam)

If you try <2> on the previous simple illegal C++ program
you will obtain a main() like this:
int main() {
A xxx(42);
xxx.run();
return 0;
}
and now, when you compile it with using the Microsoft C++ compiler
you will correctly obtain the error:
error C2259: 'A' : cannot instantiate abstract class ...

Short Story
===========

IMHO a C++ program error is masked by a bug
of the Microsoft C++ 6.0 compiler.
Accurate code inspection -or- using an alternative
correct C++ compiler (like g++)
may help in finding the error.

- Dario


  #2  
Old July 19th, 2005, 05:56 PM
Ron Natalie
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report


"Dario" <dario@despammed.com> wrote in message news:bk9893$agg$1@grillo.cs.interbusiness.it...

I don't know why you feel comp.lang.c++ cares about Microsnot compiler bugs.
[color=blue]
> This program is illegal because in the main() function
> there is a call to A constructor but A cannot be constructed
> because it does not declare the onEvent function.[/color]

Absolutely incorect. You can not call constructors. What you have
is an attempt to create a temporary object initialzed with 42. But you
are right in that A is still abstract and the program is ill-formed when it tries
to create an A object.


  #3  
Old July 19th, 2005, 05:57 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report

On Thu, 18 Sep 2003 09:32:04 -0400, "Ron Natalie" <ron@sensor.com> wrote:
[color=blue]
>
>"Dario" <dario@despammed.com> wrote in message news:bk9893$agg$1@grillo.cs.interbusiness.it...
>
>I don't know why you feel comp.lang.c++ cares about Microsnot compiler bugs.[/color]

"Microsoft", not a deragatory variant.

Many here care because they're in the position of using actual compilers
to produce actual code.

The more you know about compiler errors like that, the easier it is to
conclude whether some error is a language violation or a compiler error
(in the old days that was obvious, 'cause a compiler was almost never
wrong, but with modern C++ it's another story).


[color=blue][color=green]
>> This program is illegal because in the main() function
>> there is a call to A constructor but A cannot be constructed
>> because it does not declare the onEvent function.[/color]
>
>Absolutely incorect. You can not call constructors.[/color]

There's enough people on this group discussing basic _terminology_ if not
old-timers too. But for the record:

a constructor can be called.

C++ merely couples that with object allocation, as does all other languages
I know (since that's the point of a constructor), so:

a constructor for type T cannot be called on an existing type T object ...

.... by using conventional syntax, and it cannot be so called at all in a well-
defined way (using placement new that way is, I think, undefined behavior,
unless the existing object is destroyed first via explicit call of destructor).

  #4  
Old July 19th, 2005, 05:57 PM
Kanon Wood
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report

Comments below.

"Alf P. Steinbach" <alfps@start.no> wrote in message
news:3f69d939.531088046@News.CIS.DFN.DE...[color=blue]
> On Thu, 18 Sep 2003 09:32:04 -0400, "Ron Natalie" <ron@sensor.com> wrote:
>[color=green]
> >
> >"Dario" <dario@despammed.com> wrote in message[/color][/color]
news:bk9893$agg$1@grillo.cs.interbusiness.it...[color=blue][color=green]
> >
> >I don't know why you feel comp.lang.c++ cares about Microsnot compiler[/color][/color]
bugs.[color=blue]
>
> "Microsoft", not a deragatory variant.
>
> Many here care because they're in the position of using actual compilers
> to produce actual code.
>
> The more you know about compiler errors like that, the easier it is to
> conclude whether some error is a language violation or a compiler error
> (in the old days that was obvious, 'cause a compiler was almost never
> wrong, but with modern C++ it's another story).
>
>
>[color=green][color=darkred]
> >> This program is illegal because in the main() function
> >> there is a call to A constructor but A cannot be constructed
> >> because it does not declare the onEvent function.[/color]
> >
> >Absolutely incorect. You can not call constructors.[/color]
>
> There's enough people on this group discussing basic _terminology_ if not
> old-timers too. But for the record:
>
> a constructor can be called.
>
> C++ merely couples that with object allocation, as does all other[/color]
languages[color=blue]
> I know (since that's the point of a constructor), so:
>
> a constructor for type T cannot be called on an existing type T object[/color]
....[color=blue]
>
> ... by using conventional syntax, and it cannot be so called at all in a[/color]
well-[color=blue]
> defined way (using placement new that way is, I think, undefined behavior,
> unless the existing object is destroyed first via explicit call of[/color]
destructor).[color=blue]
>[/color]

The example at the bottom allocates enough memory for 10 CMyObj's. It uses
the following statements to construct and destruct the objects as needed.

m_aData[i].CBankT::CBankT();
m_aData[i].CBankT::~CBankT();


Is this a compiler loophole, or valid code?

-Kanon



// Creates a static block of memory
// that can hold several T objects.
template <class T>
class CBank_t
{
class CBankT : public T {};

CBankT * m_aData;
bool * m_aInUse;

int m_iCapacity;
int m_iSize;

public:
CBank_t(int iCapacity)
{
// allocate memory for future use
m_aData = (CBankT*)malloc(iCapacity*sizeof(CBankT));
m_aInUse = new bool[iCapacity];
memset(m_aInUse, 0, sizeof(bool)*iCapacity);

m_iSize = 0;
m_iCapacity = iCapacity;
}

T * Create()
{
int i = 0;
// Find an object not in use
while (i < m_iCapacity && m_aInUse[i])
i++;

if (i >= m_iCapacity)
return NULL;

m_aData[i].CBankT::CBankT();
m_aInUse[i] = true;
m_iSize++;

return &(m_aData[i]);
}

void Release(T * pObj)
{
int i = pObj - m_aData;

if (i < m_iCapacity)
{
m_aData[i].CBankT::~CBankT();
m_aInUse = false;
m_iSize--;
}
}

int GetSize()
{return m_iSize;}

int GetCapacity()
{return m_iCapacity;}
};

// Simple do nothing class
class CMyObj
{
int m_iX;
public:
CMyObj()
{m_iX = 0;}
~CMyObj()
{m_iX = -1;}

void SetX(int x)
{m_iX = x;}

int GetX()
{return m_iX;}

};


int main()
{
CBank_t <CMyObj> theBank(10);

CMyObj * pObj1, *pObj2;

pObj1 = theBank.Create();
pObj2 = theBank.Create();

pObj1->SetX(3);
pObj1->GetX();

pObj2->SetX(5);
pObj2->GetX();

theBank.Release(pObj1);
theBank.Release(pObj2);

return 0;
}




  #5  
Old July 19th, 2005, 05:57 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report

On Thu, 18 Sep 2003 13:14:54 -0500, "Kanon Wood" <Kanonw@yahoo.com> wrote:
[color=blue]
>The example at the bottom allocates enough memory for 10 CMyObj's. It uses
>the following statements to construct and destruct the objects as needed.
>
> m_aData[i].CBankT::CBankT();
>
>Is this a compiler loophole, or valid code?[/color]

That's a compiler loophole _if_ any compiler accepts it. More
specifically it's a compiler error. To construct objects in-place use
placement new (look it up).


[color=blue]
> m_aData[i].CBankT::~CBankT();[/color]

This is technically OK, I think (never used that feature, so
I'd have to check the syntax ;-) ).

That does not mean it's OK at any other level.



[color=blue]
>// Creates a static block of memory
>// that can hold several T objects.
>template <class T>
>class CBank_t
>{
> class CBankT : public T {};
>
> CBankT * m_aData;
> bool * m_aInUse;
>
> int m_iCapacity;
> int m_iSize;
>
>public:
> CBank_t(int iCapacity)
> {
>// allocate memory for future use
> m_aData = (CBankT*)malloc(iCapacity*sizeof(CBankT));[/color]


Ouch.


Hth.,

- Alf

  #6  
Old July 19th, 2005, 05:57 PM
Kanon Wood
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report


"Alf P. Steinbach" <alfps@start.no> wrote in message
news:3f69f7e6.538941281@News.CIS.DFN.DE...[color=blue]
> On Thu, 18 Sep 2003 13:14:54 -0500, "Kanon Wood" <Kanonw@yahoo.com> wrote:
>[color=green]
> >The example at the bottom allocates enough memory for 10 CMyObj's. It[/color][/color]
uses[color=blue][color=green]
> >the following statements to construct and destruct the objects as needed.
> >
> > m_aData[i].CBankT::CBankT();
> >
> >Is this a compiler loophole, or valid code?[/color]
>
> That's a compiler loophole _if_ any compiler accepts it. More
> specifically it's a compiler error. To construct objects in-place use
> placement new (look it up).
>
>[/color]

VC 6.0 compiles it OK, but per your advice I replaced it with placement new.
Works fine.
[color=blue]
>[color=green]
> > m_aData[i].CBankT::~CBankT();[/color]
>
> This is technically OK, I think (never used that feature, so
> I'd have to check the syntax ;-) ).
>
> That does not mean it's OK at any other level.
>
>[/color]

MSDN says it's OK to use with placement new.

[color=blue][color=green]
> > CBank_t(int iCapacity)
> > {
> >// allocate memory for future use
> > m_aData = (CBankT*)malloc(iCapacity*sizeof(CBankT));[/color]
>
>
> Ouch.[/color]

How would you suggest allocating this memory without constructing objects?
[color=blue]
>
>
> Hth.,
>[/color]

Hth?
[color=blue]
> - Alf
>[/color]

-Kanon


  #7  
Old July 19th, 2005, 05:57 PM
Kevin Goodsell
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technicalreport

Alf P. Steinbach wrote:
[color=blue]
>[color=green]
>> m_aData[i].CBankT::~CBankT();[/color]
>
>
> This is technically OK, I think (never used that feature, so
> I'd have to check the syntax ;-) ).[/color]

I didn't look at the rest of the code very carefully, but I think
usually the syntax is

object->~Object();

(because usually you are dealing with a pointer). I can't see an obvious
problem with calling it directly on the object, but I don't know about
the explicit qualification.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

  #8  
Old July 19th, 2005, 05:57 PM
Alf P. Steinbach
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report

On Thu, 18 Sep 2003 14:24:56 -0500, "Kanon Wood" <Kanonw@yahoo.com> wrote:
[color=blue][color=green][color=darkred]
>> > CBank_t(int iCapacity)
>> > {
>> >// allocate memory for future use
>> > m_aData = (CBankT*)malloc(iCapacity*sizeof(CBankT));[/color]
>>
>>
>> Ouch.[/color]
>
>How would you suggest allocating this memory without constructing objects?[/color]

I wouldn't... ;-)

As is so often the case in this group, the real problem is most probably
something else - when you find that you "need" something as ugly as that,
there is something very very wrong with the approach (it just makes things
infinitely worse that Bruce Eckel has such an example in his online book).

But anyway, in the hypotethical case (science fiction) where something like
that is really needed you might consider a std::vector<char> as buffer.


Btw., please don't crosspost to Microsoft newgroups, because that may drag
Microsoft-specific responses into [comp.lang.c++].

FUT: [comp.lang.c++].

  #9  
Old July 19th, 2005, 05:58 PM
Kevin Goodsell
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technicalreport

Kanon Wood wrote:[color=blue]
>
> How would you suggest allocating this memory without constructing objects?[/color]

operator new() (not the new operator) is one option.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

  #10  
Old July 19th, 2005, 06:03 PM
Craig Powers
Guest
 
Posts: n/a
Default Re: Microsoft runtime error R6025 Pure Virtual Function Call: a technical report

Dario wrote:[color=blue]
> This is a technical C++ post regarding the
> Microsoft runtime error R6025 Pure Virtual Function Call
> that sometime occurs in programs compiled with
> Microsoft Visual C++ 6.0.[/color]

FWIW, VC7.1 (aka VC.NET 2003) correctly identifies the error.


 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,840 network members.