please review, is it bug ?
Artak Avetyan
artak@softhome.net
Wed Jan 17 04:35:00 GMT 2001
Hi again.
First, I'd like to thank once again to all who could help me in my
previous mail, connected with friend template function declaration in
template class.
Here is a other sample. I've got very interesting results, could not
find explanation for it. Would like to know is it bug or not ? The deal
is that I destroy virtual functions' table and create it which is differ
of its previous. The same object behaves very different, depends on what
variable I use for calling virtual function. Note all pointers and
references to the same object call absolutely the same virtual function,
except the very object.
If something is not understandable, or if you have any comments or
questions please do not hesitate to contact me. Please copy and past
sample project, compile and run it. As well I'd like to test it on
different compilers, I tested it on MS VC++ and GNU's compilers. The
results are absolutely the same.
More over: In the function ' DirectCall' please comment the following
code:
// new (this) Parent; // Construct Parent's VIRTUAL TABLE
The program will work as well, it doesn't react on this code absolutely.
It is very strange, isn't it? If I destroyed virtual functions' table,
it means that it is empty, what it calls then and how? I think it
attaches table static.
Thanks for your time.
P.S. Once I asked for list of warning numbers of GNU. Anyone can help
me? I'd like to switch off some warnings, but don't know their numbers.
With regards,
Artak.
// =====================================
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <new.h>
#define TRACE(szMsg) fwrite((szMsg), 1, strlen((szMsg)), stdout)
class Foreign
{
public: // Constructor / Destructor
Foreign() {}
virtual ~Foreign() {}
public: // virtual function
virtual void Message()
{
TRACE("Message from class Foreign.\n");
}
};
class Parent
{
public: // Constructor / Destructor
Parent();
virtual ~Parent();
public:
virtual void Message();
protected:
char* m_pParentBuff;
};
class Child : public Parent
{
public: // Constructor/Destructor
Child();
virtual ~CChild();
public:
virtual void Message();
public:
void DirectCall();
void ForeignCall();
protected:
char *m_pChildBuff;
};
///////////////////////////////////////////////////////////////
// Parent class member functions implementation
Parent::Parent()
{
m_pParentBuff = new char[10];
}
Parent::~Parent()
{
if (m_pParentBuff != 0)
{
delete [] m_pParentBuff;
m_pParentBuff = 0;
}
}
void Parent::Message()
{ // Traces message
TRACE("The function ' Message ' was called from class Parent.\n");
}
/////////////////////////////////////////////////////////////////
// Child class member functions implementation
Child::Child()
{
m_pChildBuff = new char[20];
}
Child::~Child()
{
if (m_pChildBuff != 0)
{
delete [] m_pChildBuff;
m_pChildBuff = 0;
}
}
void Child::Message()
{
TRACE("The function ' Message ' was called from class Child
!!!.\n");
}
void Child::DirectCall()
{
// Here I destroy VIRTUAL FUNCTIONS' TABLE
// of classes Child and Parent
this->~Child();
new (this) Parent; // Construct Parent's VIRTUAL TABLE
TRACE("The function ' DirecCall ' was called. Watch results.\n");
}
void Child::ForeignCall()
{
this->~Child();
new (this) Foreign;
TRACE("The function ' ForeignCall ' was called. Watch results.\n");
}
int main(int argc, char *argv[ ], char *envp[ ])
{
Child child;
Child& refChild;
Child* pChild;
Parent* pParent;
pChild = &child;
refChild = child;
pParent = &child;
TRACE("Start Testing before calling ' Direct Call '.\n\n");
TRACE("'child.Message() ' s result : .\n'");
child.Message();
TRACE("'refChild.Message() ' s result : .\n'");
refChild.Message();
TRACE("'pChild->Message() ' s result : .\n'");
pChild->Message();
TRACE("'pParent->Message() ' s result : .\n'");
pParent->Message();
// All of this functions call virtual void Message() of class Child
// While everything is OK.
// PAY ATTENTION HERE !!!
child.DirectCall();
TRACE("Start Testing after calling ' Direct Call '.\n\n");
TRACE("'child.Message() ' s result : .\n'");
child.Message();
TRACE("'refChild.Message() ' s result : .\n'");
refChild.Message();
TRACE("'pChild->Message() ' s result : .\n'");
pChild->Message();
TRACE("'pParent->Message() ' s result : .\n'");
pParent->Message();
// RESULTS ARE DIFFER !!!!
// PAY ATTENTION HERE !!!
child.ForeignCall();
TRACE("Start Testing before calling ' Direct Call '.\n\n");
TRACE("'child.Message() ' s result : .\n'");
child.Message();
TRACE("'refChild.Message() ' s result : .\n'");
refChild.Message();
TRACE("'pChild->Message() ' s result : .\n'");
pChild->Message();
TRACE("'pParent->Message() ' s result : .\n'");
pParent->Message();
// RESULTS ARE DIFFER AS WELL !!!
TRACE("End of test ///////////////////////////.\n");
return 0;
}
More information about the Gcc-bugs
mailing list