g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
<== Date ==> <== Thread ==>

Subject: Re: bcc55
From: Dirk Zimoch <dirk.zimoch@psi.ch>
To: Andrew Johnson <anj@aps.anl.gov>
Cc: tech-talk@aps.anl.gov
Date: Mon, 12 Nov 2012 09:35:49 +0100
On 09.11.2012 17:33, Andrew Johnson wrote:
Hi Jens, Dirk,

On 09.11.2012 11:26, "Ing.- Büro Austel" wrote:
using the free downloadable bcc55 compiler I get the error

../../../src/libCom/cxxTemplates/epicsOnce.cpp:
Error E2316 ../../../src/libCom/cxxTemplates/epicsSingleton.h 112:
'epicsSingleton<TYPE>::reference::operator =(const
epicsSingleton<TYPE>::reference&) is not a
member of 'epicsSingleton<TYPE>::reference'
***1 error in Compile ***

Is bcc55 the old Borland C++ compiler, or have they published a new version
recently?  What C++ standard does it recognize?  We used to support the
Borland compiler quite a long time ago, but we dropped it because it wasn't
keeping up with the C++ standards process.

On 2012-11-09 Dirk Zimoch wrote:
It seems the "archaic Tornado gnu compiler" and bcc55 don't quite agree
on what valid C++ template syntax looks like.

The syntax looks strange to me, too. I simplified it to:

reference&  operator = ( const reference&  );

And it compiles fine with several gcc versions for Linux and as well
with the gcc versions of vxWorks 5.5, 6.3 and 6.7. Maybe bcc is happy
with this change, too?

BTW: This is exactly how the operator = looked like in 3.14.8, except
that it was private and is now public. Does anyone remember why it had
been changed?

According to the commit that made this change, it was for the Tornado 2.0.2
g++ compiler that came with vxWorks 5.4.2.  We don't support that compiler any
more, so we could probaby switch the definition back now (Jeff Hill would have
to agree to that), but if bcc55 is the old Borland compiler I don't think that
will be sufficient.

- Andrew

I tried with vxWorks 5.4.2 (Tornado 2.0.2) and indeed got an error:

In file included from ../../../src/libCom/cxxTemplates/epicsOnce.cpp:29:
../../../src/libCom/cxxTemplates/epicsSingleton.h:112: new declaration `typename epicsSingleton<TYPE>::reference & epicsSingleton<TYPE>::reference::operator =(const class epicsSingleton<TYPE>::reference &)' ../../../src/libCom/cxxTemplates/epicsSingleton.h:58: ambiguates old declaration `class epicsSingleton<TYPE>::reference & epicsSingleton<TYPE>::reference::operator =(const class epicsSingleton<TYPE>::reference &)'

It seems than the old compiler is not quite happy with the keyword typename (which only appears in epicsSingleton.h).

So I replaced typename with class everywhere in the file and base R3.14.12.2 compiled fine with all versions of gcc that I have tried:

2.95 (Tornado 2.0.2, ppc604)
2.98 (Tornado 2.0, ppc604)
3.4.3 (MontaVista 3.4.3, armv5teb)
3.4.4 (vxWorks 6.3, ppc603)
4.0.2 (crosstool 0.43, ppc405)
4.1.2 (vxWorks 6.7, ppc604)
4.1.2 (Scientific Linux 5.4, x86)
4.4.4 (Scientific Linux 6.0, x86 and x86_64)
4.6.4 (eldk 5.2, ppc e500v2)

Modified version is attached.

Dirk
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
*     National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
*     Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution. 
\*************************************************************************/

/*
 *  Revision-Id: ralph.lange@gmx.de-20110808163119-szktwmb8pwbw5cec
 *
 *  Author: Jeffrey O. Hill
 *
 */

#ifndef epicsSingleton_h
#define epicsSingleton_h

#include <new>

#include "shareLib.h"
#include "epicsAssert.h"

class epicsShareClass SingletonUntyped {
public:
    SingletonUntyped ();
    ~SingletonUntyped ();
    typedef void * ( * PBuild ) ();
    void incrRefCount ( PBuild );
    typedef void ( * PDestroy ) ( void * );
    void decrRefCount ( PDestroy );
    void * pInstance () const;
private:
    void * _pInstance;
    std :: size_t _refCount;
    SingletonUntyped ( const SingletonUntyped & );
    SingletonUntyped & operator = ( const SingletonUntyped & );
};

// This class exists for the purpose of avoiding file scope
// object chicken and egg problems. It implements thread safe
// lazy initialization. To avoid locking overhead retain a
// copy of the epicsSingleton :: reference for future use. 
template < class TYPE >
class epicsSingleton {
public:
    class reference {
    public:
        reference ( epicsSingleton & );
        reference ( const reference & );
        ~reference ();
        reference & 
	    operator = ( const reference & );
        TYPE * operator -> ();
        const TYPE * operator -> () const;
        TYPE & operator * ();
        const TYPE & operator * () const;
    private:
        epicsSingleton * _pSingleton;
    };
    friend class reference;
    epicsSingleton () {}
    // mutex lock/unlock pair overhead incured
    // when either of these are called
    reference getReference ();
    const reference getReference () const;
private:
    SingletonUntyped _singletonUntyped;
    static void * _build ();
    static void _destroy ( void * );
    epicsSingleton ( const epicsSingleton & );
    epicsSingleton & operator = ( const epicsSingleton & );
};

template < class TYPE >
inline epicsSingleton < TYPE > :: reference :: 
    reference ( epicsSingleton & es ):
    _pSingleton ( & es ) 
{
    es._singletonUntyped.
        incrRefCount ( & epicsSingleton < TYPE > :: _build );
}

template < class TYPE >
inline epicsSingleton < TYPE > :: reference :: 
    reference ( const reference & ref ) :
    _pSingleton ( ref._pSingleton )
{
    assert ( _pSingleton );
    _pSingleton->_singletonUntyped.
        incrRefCount ( & epicsSingleton < TYPE > :: _build );
}

template < class TYPE >
inline epicsSingleton < TYPE > :: reference :: 
    ~reference ()
{
    assert ( _pSingleton );
    _pSingleton->_singletonUntyped.
        decrRefCount ( & epicsSingleton < TYPE > :: _destroy );
}

template < class TYPE >
class epicsSingleton < TYPE > :: reference & 
    epicsSingleton < TYPE > :: reference :: 
        operator = ( const reference & ref )
{
    if ( _pSingleton != ref._pSingleton ) {
        assert ( _pSingleton );
        _pSingleton->_singletonUntyped.
            decrRefCount ( epicsSingleton < TYPE > :: _destroy );
        _pSingleton = ref._pSingleton;
        assert ( _pSingleton );
        _pSingleton->_singletonUntyped.
            incrRefCount ( & epicsSingleton < TYPE > :: _build ); 
    }
    return *this;
}

template < class TYPE >
inline TYPE * 
    epicsSingleton < TYPE > :: reference :: 
        operator -> ()
{ 
    assert ( _pSingleton );
    return reinterpret_cast < TYPE * > 
            ( _pSingleton->_singletonUntyped.pInstance () ); 
}

template < class TYPE >
inline const TYPE * 
    epicsSingleton < TYPE > :: reference :: 
        operator -> () const 
{
    assert ( _pSingleton );
    return reinterpret_cast < const TYPE * > 
            ( _pSingleton->_singletonUntyped.pInstance () ); 
}

template < class TYPE >
inline TYPE & 
    epicsSingleton < TYPE > :: reference :: 
        operator * () 
{
    return * this->operator -> ();
}

template < class TYPE >
inline const TYPE & 
    epicsSingleton < TYPE > :: reference :: 
            operator * () const 
{
    return * this->operator -> ();
}

inline SingletonUntyped :: SingletonUntyped () : 
    _pInstance ( 0 ), _refCount ( 0 )
{
}

inline void * SingletonUntyped :: pInstance () const
{
    return _pInstance;
}

inline SingletonUntyped :: ~SingletonUntyped ()
{
    // we dont assert fail on non-zero _refCount
    // and or non nill _pInstance here because this
    // is designed to tolarate situations where 
    // file scope epicsSingleton objects (which 
    // theoretically dont have storage lifespan 
    // issues) are deleted in a non-determanistic 
    // order
#   if 0
        assert ( _refCount == 0 );
        assert ( _pInstance == 0 );
#   endif
}

template < class TYPE >
void * epicsSingleton < TYPE > :: _build ()
{
    return new TYPE ();
}

template < class TYPE >
void epicsSingleton < TYPE > :: 
    _destroy ( void * pDestroyTypeless )
{
    TYPE * pDestroy = 
        reinterpret_cast < TYPE * > ( pDestroyTypeless );
    delete pDestroy;
}

template < class TYPE >
inline class epicsSingleton < TYPE > :: reference 
    epicsSingleton < TYPE > :: getReference ()
{
    return reference ( * this );
}

template < class TYPE >
inline const class epicsSingleton < TYPE > :: reference 
    epicsSingleton < TYPE > :: getReference () const
{
    epicsSingleton < TYPE > * pConstCastAway = 
        const_cast < epicsSingleton < TYPE > * > ( this );
    return pConstCastAway->getReference ();
}

#endif // epicsSingleton_h


References:
bcc55 "Ing.- Büro Austel"
Re: bcc55 Dirk Zimoch
Re: bcc55 Dirk Zimoch
Re: bcc55 Andrew Johnson

Navigate by Date:
Prev: Senior Software Engineer needed at MSU's FRIB careers
Next: RE: procServ softIOC server - V2.6.0 released Mark Rivers
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
Navigate by Thread:
Prev: Re: bcc55 Andrew Johnson
Next: Linkam temperature controller CI94 serial programming 洪春霞
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
ANJ, 18 Nov 2013 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·