473,469 Members | 1,522 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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

Jul 19 '05 #1
9 46565

"Dario" <da***@despammed.com> wrote in message news:bk**********@grillo.cs.interbusiness.it...

I don't know why you feel comp.lang.c++ cares about Microsnot compiler bugs.
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.


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.
Jul 19 '05 #2
On Thu, 18 Sep 2003 09:32:04 -0400, "Ron Natalie" <ro*@sensor.com> wrote:

"Dario" <da***@despammed.com> wrote in message news:bk**********@grillo.cs.interbusiness.it...

I don't know why you feel comp.lang.c++ cares about Microsnot compiler bugs.


"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).
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.


Absolutely incorect. You can not call constructors.


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).

Jul 19 '05 #3
Comments below.

"Alf P. Steinbach" <al***@start.no> wrote in message
news:3f****************@News.CIS.DFN.DE...
On Thu, 18 Sep 2003 09:32:04 -0400, "Ron Natalie" <ro*@sensor.com> wrote:

"Dario" <da***@despammed.com> wrote in message news:bk**********@grillo.cs.interbusiness.it...

I don't know why you feel comp.lang.c++ cares about Microsnot compiler
bugs.
"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).
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.
Absolutely incorect. You can not call constructors.


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).


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


Jul 19 '05 #4
On Thu, 18 Sep 2003 13:14:54 -0500, "Kanon Wood" <Ka****@yahoo.com> wrote:
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?
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).
m_aData[i].CBankT::~CBankT();
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.

// 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));

Ouch.
Hth.,

- Alf

Jul 19 '05 #5

"Alf P. Steinbach" <al***@start.no> wrote in message
news:3f****************@News.CIS.DFN.DE...
On Thu, 18 Sep 2003 13:14:54 -0500, "Kanon Wood" <Ka****@yahoo.com> wrote:
The example at the bottom allocates enough memory for 10 CMyObj's. It usesthe following statements to construct and destruct the objects as needed.

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

Is this a compiler loophole, or valid code?
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).


VC 6.0 compiles it OK, but per your advice I replaced it with placement new.
Works fine.
m_aData[i].CBankT::~CBankT();
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.


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

CBank_t(int iCapacity)
{
// allocate memory for future use
m_aData = (CBankT*)malloc(iCapacity*sizeof(CBankT));

Ouch.


How would you suggest allocating this memory without constructing objects?


Hth.,

Hth?
- Alf


-Kanon
Jul 19 '05 #6
Alf P. Steinbach wrote:
m_aData[i].CBankT::~CBankT();

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


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.

Jul 19 '05 #7
On Thu, 18 Sep 2003 14:24:56 -0500, "Kanon Wood" <Ka****@yahoo.com> wrote:
> CBank_t(int iCapacity)
> {
>// allocate memory for future use
> m_aData = (CBankT*)malloc(iCapacity*sizeof(CBankT));

Ouch.


How would you suggest allocating this memory without constructing objects?


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++].

Jul 19 '05 #8
Kanon Wood wrote:

How would you suggest allocating this memory without constructing objects?


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.

Jul 19 '05 #9
Dario wrote:
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.


FWIW, VC7.1 (aka VC.NET 2003) correctly identifies the error.
Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Bob Bamberg | last post by:
Hello All, I have been trying without luck to get some information on debugging the Runtime Error R6025 - Pure Virtual Function Call. I am working in C++ and have only one class that is derived...
11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
6
by: pakis | last post by:
I am having a problem of pure virtual function call in my project. Can anyone explaine me the causes of pure virtual function calls other than calling a virtual function in base class? Thanks
21
by: sks | last post by:
Hi , could anyone explain me why definition to a pure virtual function is allowed ?
4
by: Steve | last post by:
hi all, i'm using DHTML to generate a dynamic table with adding removing and sorting rows the thing is after a row has been added at a position that i specify, if i try to delete it i get this...
17
by: Fabry | last post by:
Hi All, I'm new of this group and I do not know if this is the correct group for my question. I have a DLL with its export library (.lib) wrote in Borland C++ 6. In borland everything is OK and...
8
by: ibayley | last post by:
Hi, could someone guide me step by step how to fix this problem. runtime error -pure virtual function call I have posted the entire image and message here ...
2
by: jazzy | last post by:
Hey can some one help with this I get this erroe message every time I try to open up my Windows Live Messenger? R6025 pure virtual function call. Thanks
2
by: =?Utf-8?B?R2hhbmFzaHlhbQ==?= | last post by:
I am using the COM object in .NET C# Client and I am getting an error "R6025 Pure Virtual function called".While running the application in the debugger also I noticed the error but call stack did...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.