Strange Bug?

This is a discussion on Strange Bug? within the C++ Programming forums, part of the General Programming Boards category; Does anyone know what could cause this behavior? or if this is bug in msvc++ 7.1? Code: class WriteOid : ...

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    470

    Post Strange Bug?

    Does anyone know what could cause this behavior? or if this is bug in msvc++ 7.1?
    Code:
    class WriteOid : public WriteNode
    {
        std::ostream& m_os;
    public:
        WriteOid(std::ostream& out);
    
    
        void operator()(OidValueType value, const OidMap& oidMap)
        {
            m_os << typeid(*value.first).name() << std::endl;   // write class identifier
            m_os << value.second << std::endl;                 // write unique object id
        }
    
    };
    
    class Serialization
    {
        friend class WriteObject;
    public:
        typedef counted_ptr<Serialization> Ptr;
    
        virtual Serialization* Clone() const = 0;
        virtual void Accept(Visitor* visitor) = 0;
        virtual void SerializeAll(std::ostream& os);
    private:
        OidVisitor::Ptr BuildOidTable();
        InvOid::Ptr LoadOidTable(std::istream& is);
    
        void SerializeOidTable(OidVisitor::Ptr v, std::ostream& out);
        virtual void Serialize(std::ostream& os, const OidMap& oidMap) = 0;
        //static std::map<std::string, Serialization*> m_typeMap;  
    };
    Switching the order of these two classes seems to corrupts the type_info data from the virtual table because the type_info.name() of a class derived from Serialization is returning "class serial::Serialization" instead of the derived class. Yet before the parameter is passed into to operator()(OidValueType... typeinfo(*value.first).name() returns the correct string. Thus this problem seems to be because of the order of template instantiation. If the call to operator()() occurs before Serialization in the sourcefile, the problem occurs., and so writing WriteOid like this does not exhibit the problem.

    PHP Code:
    class WriteOid : public WriteNode
    {
        
    std::ostreamm_os;
    public:
        
    WriteOid(std::ostreamout);


        
    void operator()(OidValueType value, const OidMapoidMap);
    };

    class 
    Serialization
    {
        
    friend class WriteObject;
    public:
        
    typedef counted_ptr<SerializationPtr;

        
    virtual Serialization* Clone() const = 0;
        
    virtual void Accept(Visitorvisitor) = 0;
        
    virtual void SerializeAll(std::ostreamos);
    private:
        
    OidVisitor::Ptr BuildOidTable();
        
    InvOid::Ptr LoadOidTable(std::istreamis);

        
    void SerializeOidTable(OidVisitor::Ptr vstd::ostreamout);
        
    virtual void Serialize(std::ostreamos, const OidMapoidMap) = 0;
        
    //static std::map<std::string, Serialization*> m_typeMap;  
    };

    inline void WriteOid::operator()(OidValueType value, const OidMapoidMap)
    {
        
    m_os << typeid(*value.first).name() << std::endl;   // write class identifier
        
    m_os << value.second << std::endl;                 // write unique object id

    Though writing it like this will

    Code:
    class WriteOid : public WriteNode
    {
        std::ostream& m_os;
    public:
        WriteOid(std::ostream& out);
    
    
        void operator()(OidValueType value, const OidMap& oidMap);
    };
    
    
    inline void WriteOid::operator()(OidValueType value, const OidMap& oidMap)
    {
        m_os << typeid(*value.first).name() << std::endl;   // write class identifier
        m_os << value.second << std::endl;                 // write unique object id
    }
    
    
    class Serialization
    {
        friend class WriteObject;
    public:
        typedef counted_ptr<Serialization> Ptr;
    
        virtual Serialization* Clone() const = 0;
        virtual void Accept(Visitor* visitor) = 0;
        virtual void SerializeAll(std::ostream& os);
    private:
        OidVisitor::Ptr BuildOidTable();
        InvOid::Ptr LoadOidTable(std::istream& is);
    
        void SerializeOidTable(OidVisitor::Ptr v, std::ostream& out);
        virtual void Serialize(std::ostream& os, const OidMap& oidMap) = 0;
    };

  2. #2
    Normal vector Carlos's Avatar
    Join Date
    Sep 2001
    Location
    Budapest
    Posts
    463
    Sorry, don't have time to analyze your code, but maybe you forgot to enable RTTI ( /GR compiler switch).

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    There's no compiler warnings and I've made sure the rtti is on. I think I'll try to code up a smaller example that has this problem and post it.

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    I think I solved the problem. Code such as this will compile without warnings on msvc++ but uses a typeid on the incomplete class Base.


    Code:
    #include <iostream>
    #include <map>
    
    
    class Base;
    
    typedef int ID;
    typedef std::map<Base*, ID> MapType;
    
    
    class Print
    {
    public:
        void operator()(MapType::value_type v)
        {
            std::cout << "name =    " << typeid(*v.first).name() << std::endl;
        }
    
    };
    class Base 
    {
    public:
        virtual ~Base() { } // make sure to use rtti
    };
    
    
    
    class Sequence
    {
        MapType m;
    public:
        template<typename F>
        void Foreach(F f)
        {
            typedef MapType::iterator MI;
    
            for (MI i = m.begin(); i != m.end(); ++i)
                f(*i);
        }
    
        void Insert(Base* base, ID val)
        {
            m.insert(std::make_pair(base, val));
        }
    
        ~Sequence()
        {
            typedef MapType::iterator MI;
    
            for (MI i = m.begin(); i != m.end(); ++i)
                delete i->first;
        }
    };
    
    
    class A : public Base { };
    class B : public Base { };
    
    
    
    int main(void)
    {
        Sequence sq; 
      
        sq.Insert(new A(), 1);
        sq.Insert(new B(), 2);
        sq.Insert(new A(), 3);
    
        sq.Foreach(Print());
    
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange bug with Input stream
    By Chazij in forum C++ Programming
    Replies: 12
    Last Post: 11-18-2008, 03:52 PM
  2. Strange bug....
    By beene in forum C++ Programming
    Replies: 4
    Last Post: 10-11-2006, 11:55 AM
  3. Strange bug with DevCPP v 4.9.9.2
    By domhnall4h in forum C++ Programming
    Replies: 4
    Last Post: 03-13-2006, 06:10 AM
  4. Very strange bug...
    By JaWiB in forum Tech Board
    Replies: 6
    Last Post: 04-27-2003, 01:56 PM
  5. Very Strange Bug
    By Asm_Freak in forum C++ Programming
    Replies: 0
    Last Post: 02-09-2003, 10:04 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21