This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
3.2.2 vs. 3.3.2 - forward declaration
- From: "Ilja Golstein" <ilejn at yandex dot ru>
- To: gcc-help at gcc dot gnu dot org
- Date: Fri, 17 Dec 2004 18:45:06 +0300 (MSK)
- Subject: 3.2.2 vs. 3.3.2 - forward declaration
- Reply-to: ilejn at yandex dot ru
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.