3.2.2 vs. 3.3.2 - forward declaration

Ilja Golstein ilejn@yandex.ru
Fri Dec 17 15:45:00 GMT 2004


Hello!

What do you think about this difference between 3.2.2 and 3.3.2
regarding class defined after used in the same compilation unit?

I failed to find anything related in Changelogs.

As far as I know modern MS compilers are as tolerant as 3.2.2.

Before line of '='s goes 3.2.2, after 3.3.2 and the source.



# g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
# g++ -DDEFINED_BEFORE decl_after_inst.cpp 
# ./a.out
MyValueTableLine::MyValueTableLine
AnObject::AnObject
MyValueTableLine::~MyValueTableLine
Before end of main
# g++ decl_after_inst.cpp 
# ./a.out
MyValueTableLine::MyValueTableLine
AnObject::AnObject
MyValueTableLine::~MyValueTableLine
Before end of main

================================

# g++ -v
Reading specs from /usr/lib/gcc-lib/i386-asplinux-linux/3.3.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-asplinux-linux
Thread model: posix
gcc version 3.3.2 20031022 (ASPLinux 3.3.2-1)
# g++ -DDEFINED_BEFORE decl_after_inst.cpp 
# ./a.out
MyValueTableLine::MyValueTableLine
AnObject::AnObject
MyValueTableLine::~MyValueTableLine
Before end of main
# g++ decl_after_inst.cpp 
decl_after_inst.cpp: In member function `void SmartPtrBase<T>::acquire() [with 
   T = MyValueTableLine]':
decl_after_inst.cpp:28:   instantiated from `SmartPtrBase<T>::SmartPtrBase(T*) [with T = MyValueTableLine]'
decl_after_inst.cpp:79:   instantiated from here
decl_after_inst.cpp:38: error: `acquire' undeclared (first use this function)
decl_after_inst.cpp:38: error: (Each undeclared identifier is reported only 
   once for each function it appears in.)
decl_after_inst.cpp: In member function `void SmartPtrBase<T>::release() [with 
   T = MyValueTableLine]':
decl_after_inst.cpp:31:   instantiated from `SmartPtrBase<T>::~SmartPtrBase() [with T = MyValueTableLine]'
decl_after_inst.cpp:79:   instantiated from here
decl_after_inst.cpp:43: error: `release' undeclared (first use this function)
decl_after_inst.cpp:44: warning: invalid use of undefined type `struct 
   MyValueTableLine'
decl_after_inst.cpp:55: warning: forward declaration of `struct 
   MyValueTableLine'
# cat decl_after_inst.cpp 
#include <iostream> 

template <typename T>
class Refcountable
{
 public:
    Refcountable() 
        : m_refcount(0)
    { }

   long acquire() 
    { return ++m_refcount; }

    long release() 
    { return --m_refcount; }

 private:
    long m_refcount;
};

template <typename T>
class SmartPtrBase 
{
 public:

    explicit SmartPtrBase(T* p = 0)
        : m_ptr(p)
    { acquire(); }
    
    ~SmartPtrBase()
    { release(); }
protected:
    
    void acquire()
    {
        if (m_ptr) 
            m_ptr->acquire(); 
    }

    void release()
    {
        if (m_ptr &&  !m_ptr->release())
            delete m_ptr;
    }

 protected:
    T* m_ptr; // pointer to the managed object or 0;
};



/********************************************/
class MyValueTableLine;

typedef SmartPtrBase<MyValueTableLine>  MyValueTableLinePtr;

class AnObject
{
    MyValueTableLinePtr mvtl;
 public:
    AnObject(MyValueTableLine *mvtl_);
};

#ifdef DEFINED_BEFORE
class MyValueTableLine 
    :public Refcountable<MyValueTableLine>
{
 public:
    MyValueTableLine(){std::cout << "MyValueTableLine::MyValueTableLine" << std::endl;}
    ~MyValueTableLine(){std::cout << "MyValueTableLine::~MyValueTableLine" << std::endl;}
};
#endif


AnObject::AnObject(MyValueTableLine *mvtl_)
    :mvtl(mvtl_)
{
    std::cout << "AnObject::AnObject" << std::endl;
};


#ifndef DEFINED_BEFORE
class MyValueTableLine 
    :public Refcountable<MyValueTableLine>
{
 public:
    MyValueTableLine(){std::cout << "MyValueTableLine::MyValueTableLine" << std::endl;}
    ~MyValueTableLine(){std::cout << "MyValueTableLine::~MyValueTableLine" << std::endl;}
};
#endif


int main(int argc, char **argv)
{
    {
        MyValueTableLine* mvtl = new MyValueTableLine;
        AnObject ao(mvtl);
    }
    std::cout << "Before end of main" << std::endl;
}
#

Many thanks.

-- 
Best regards
Ilja Golshtein

PS. Of course, this silly not-so-smart pointers for demonstration only.



More information about the Gcc-help mailing list