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