views:

158

answers:

4

Hi All,

I am porting a very large code base and I am having more difficulty with old code.

For example, this causes a compiler error:

inline CP_M_ReferenceCounted *
FrAssignRef(CP_M_ReferenceCounted * & to, CP_M_ReferenceCounted * from)
{
    if (from) from->AddReference();
    if (to) to->RemoveReference();
    to = from;
    return to; 
}

The error is: error: expected initializer before '*' token.

How do I know what this is. I looked up inline member functions to be sure I understood and I dont think the inlining is the cause but I am not sure what is.

Another example:

template <class eachClass>
    eachClass FrReferenceIfClass(FxRC * ptr)
    {
        eachClass getObject = dynamic_cast<eachClass>(ptr);
        if (getObject)  getObject->AddReference();
        return getObject;
    }

The error is: error: template declaration of 'eachClass FrReferenceIfClass'

That is all. How do I decide what this is?. I am admittedly rusty with templates.

UPDATE:

Here is CP_M_ReferenceCounted:

#pragma once
#ifndef _H_CP_M_RefCounted
#define _H_CP_M_RefCounted

// CPLAT_Framework
#include "CP_Types.h"

CPLAT_Begin_Namespace_CPLAT

/*!
*   @class      CP_M_RefCounted
*   @brief      Mix-in class for objects that are reference counted.
*/

class CP_EXPORT CP_M_RefCounted
{
public:
    //! @name Reference
    //@{
            UInt32                      AddReference() const;
            UInt32                      RemoveReference() const;
//@}

//! @name Autorelease
//@{
        void                        Autorelease() const;
//@}

//! @name Getters
//@{
                                    /*!
                                    *   Returns the current ref count.
                                    *   
                                    *   @exception  none
                                    *   
                                    *   @return     UInt32          The current referencce count.
                                    */
        UInt32                      GetRefCount() const                                 { return( fRefCount ); }
//@}

//! @name operators
//@{
        CP_M_RefCounted&            operator = ( const CP_M_RefCounted& inRefCounted );
//@}

protected:
    //! @name Constructor / Destructor
    //@{
    //! Constructor.
                                    CP_M_RefCounted();
                                    CP_M_RefCounted( CP_M_RefCounted& inRefCounted );
//! Destructor.
virtual                             ~CP_M_RefCounted();
//@}

// class data
private:
mutable UInt32                      fRefCount;  /*! The number of references to this object. */

//========================================================================
// Platform specific routines
//========================================================================
#if TARGET_OS_MAC
#endif

#if TARGET_OS_WIN32
#endif

#if TARGET_OS_LINUX
#endif
};

template <class T> 
inline const T* CP_Autorelease(const T* inObj)
{
    if( inObj )
        inObj->Autorelease();

    return( inObj );
}

template <class T> 
inline T* CP_Autorelease(T* inObj)
{
    if( inObj )
        inObj->Autorelease();

    return( inObj );
}

    /*!
    *   @class  CP_SmartRef
   *    @brief  Template class representing a smart pointer for reference counted objects.
   */
    template <class T> 
    class CP_SmartRef
    {
    public:
        //! @name Constructor / Destructor
        //@{
        //! Constructor.
                                CP_SmartRef()
                                        :  fObj(NULL)                                   {}
                                    CP_SmartRef(
                                            T *inObj,
                                            bool inTransferOwnership=false )
                                                : fObj(inObj)                           { if( !inTransferOwnership && fObj ) fObj->AddReference(); }
                                    CP_SmartRef( const CP_SmartRef<T>& inRef )
                                        : fObj(inRef.fObj)                              { if( fObj ) fObj->AddReference(); }
                                    template <class Other>
                                    CP_SmartRef( const CP_SmartRef<Other>& inRef )
                                        : fObj(NULL)                                    { T* other = inRef.Get(); this->Reset( other ); } // assignment to local variable should prevent upcasts and cross-casts
//! Destructor.
                                    ~CP_SmartRef()                                      { if( fObj ) fObj->RemoveReference(); }
//@}

//! @name operators
//@{
        T&                          operator *() const                                  { return( *fObj ); }
        T*                          operator->() const                                  { return( fObj ); }

                                    operator T *() const                                { return( fObj ); }

        CP_SmartRef<T>&             operator = ( const CP_SmartRef<T>& inRef )          { this->Reset( inRef.fObj ); return *this; }
        template <class Other>
        CP_SmartRef<T>&             operator = ( const CP_SmartRef<Other>& inRef )      { this->Reset( inRef.Get() ); return *this; }
        CP_SmartRef<T>&             operator = ( T* inObj )                             { this->Reset( inObj ); return *this; }
        template <class Other>
        CP_SmartRef<T>&             operator = ( Other* inObj     )                         { this->Reset( inObj ); return *this; }
    //@}

    //! @name Object management
    //@{
            T                           *Get()     const                                        { return( fObj ); }
            T                           *Reset(
                                            T     *inObj,
                                            bool     inTransferOwnership = false );
            T                           *Release();
    //@}


    // class data
protected:
        T                               *fObj;

//========================================================================
// Platform specific routines
//========================================================================
#if TARGET_OS_MAC
#endif

#if TARGET_OS_WIN32
#endif

#if TARGET_OS_LINUX
#endif
};

template <class T>
T* CP_SmartRef<T>::Reset( T *inObj, bool inTransferOwnership )
{ 
    if ( inObj != fObj ) 
    {
        if( fObj )
            fObj->RemoveReference();

        fObj = inObj; 

        if( inObj && !inTransferOwnership )
            inObj->AddReference(); 
    }
    else if( inObj && inTransferOwnership )
    {
        inObj->RemoveReference();
    }

    return( fObj ); 
}

template <class T>
T* CP_SmartRef<T>::Release()
{ 
    T *tmp = fObj;

    fObj = NULL; 

    return( tmp ); 
}

CPLAT_End_Namespace_CPLAT

#endif  // _H_CP_M_RefCounted
+3  A: 

I think you have to develop some kind of feeling for the error messages of your compiler. There are worse and there are better compilers. That one is surely one of the worse. A good one points the caret to the place where the error occurs and gives hint what could be wrong.

For example in the given case, the compiler probably stops parsing the type of the declaration when it reaches CP_M_ReferenceCounted and parses it as the name of what is to be declared. The grammar allows that, because some declarations are not given a type (constructors are an example). So it expects an initializer for that name, and not a star. This hints that CP_M_ReferenceCounted probably isn't declared. Check you included the correct header.

Johannes Schaub - litb
@Johannes - I did include the correct header. I also did: typedef CP_M_ReferenceCounted FxRC; and that gives me: error: 'CP_M_ReferenceCounted' does not name a type
ML
@ML: It is also possible that you have circular inclusions, and the declaration is not visible none the less.
UncleBens
+2  A: 

I won't answer your "big picture" question, but your first error looks simple enough.

In the first snippet, my guess is that the CP_M_ReferenceCounted class hasn't been declared. You probably forgot to include "CP_M_ReferenceCounted.h" or some similarly named file. The compiler is telling you that it hasn't found a type name to which it can apply the the * (pointer) modifier, meaning that it doesn't recognize CP_M_ReferenceCounted as a valid type name. That implies that the declaration is missing, which in turn likely implies a missing header file include.

The second error is admittedly a mystery to me. I'd use "typename" instead of class since you're using eachClass as a pointer, but that shouldn't technically make any difference even if it would add clarity.

Drew Hall
I do: #include "CP_M_ReferenceCounted.h" though.
ML
It's not valid to declare a function template using the template+argument-list syntax. That's reserved for specializations. In your case, you can expect something like "FrReferenceIfClass is not a template" being emitted. This is because for a name to be followed by a template argument list, the name must be known as a template (the reason why somethines `::template` disambiguation is needed). His template declaration looks fine to me - i suspect his error is elsewhere (maybe he tries to use or overload it in invalid ways).
Johannes Schaub - litb
#Drew: The addition of <eachClass> causes this: error: expected initializer before '<' token
ML
@Johannes, ML: Whoops--brain fart. Editing now...
Drew Hall
@ML: Is `CP_M_ReferenceCounted` declared within a namespace? Maybe you need a namespace qualifier.
Fred Larson
@Fred: CP_M_ReferenceCounted yes, it is wrapped in a namespace called CPLAT like namespace CPLAT {.....}
ML
@ML you need to qualify the type name like `CPLAT::CP_M_ReferenceCounted`.
Johannes Schaub - litb
Then you probably need to use `CPLAT::CP_M_ReferenceCounted`.
Fred Larson
Yup I tried that typedef CPLAT::CP_M_ReferenceCounted FxRC; and I get: error: 'CP_M_ReferenceCounted' in namespace 'CPLAT' does not name a type
ML
Well, now you'll need to post the declaration of CP_M_ReferenceCounted.
Fred Larson
@ML: Fred wasn't saying you needed a typedef, he's saying you need to fully qualify the name CP_M_ReferenceCounted everywhere it appears in the first snippet. Or, if you prefer the typedef, make a typedef for the fully qualified name at the same scope as your function declaration, and use that typedef consistently throughout the function declaration.
Drew Hall
@Drew: Yes, but I think the typedef should be legal if `CP_M_ReferenceCounted` is declared properly. Maybe the problem is that declaration. Maybe it really isn't a type.
Fred Larson
#Drew, Fred, I edited the post with CP_M_ReferenceCounted.h above the best that I could. The typedef should be legal, I checked the old codebase from Metrowerks and that is what they have, for some reason it was commented out here.
ML
@ML: Is it supposed to be `CP_M_RefCounted`? I see that in what you posted, but not `CP_M_ReferenceCounted`.
Fred Larson
@Fred - no, that seems to be what they have in the code for sure. Weird, so with the above CP_M_RefCounted would be what I need to use.
ML
@Fred - Which still throws the same error about not naming a type.I truly just dont see this
ML
@Fred - changed the .h file name to C_M_RefCounted.h and the typedef to CPLAT::CP_M_RefCounted and viola! Thanks.
ML
+2  A: 

Others are addressing your specific errors, so I'll try addressing the big picture.

One of the goals of the Clang project is to have more helpful diagnostics. Clang's C++ support is incomplete, but depending on how much your code pushes the boundaries of the C++ language, it may be enough to give you good error messages.

For templates in the STL, try using STLFilt. I've used it several times, and it does a wonderful job of cleaning up multi-line error messages, cluttered with default template parameters, and replacing them with something understandable. I'm not sure how much it does for templates outside of the STL, but it might be worth a try.

Josh Kelley
A: 

You've shown us some problem code using CP_M_ReferenceCounted, but shown us the header file for CP_M_RefCounted. That looks like the wrong header or you've misspelt the class name.

Also, don't use leading underscores in you header include guards. Capitalisation and underscores-instead-of-spaces is OK: H_CP_M_RefCounted or H_CP_M_REFCOUNTED or CP_M_REFCOUNTED_H

quamrana
@quamrana - No, If I look at CP_ReferenceCounted.h that is that is exactly in it.
ML
@ML: So if CP_ReferenceCounted.h has class `CP_M_RefCounted` in it, why does your code snippet use `CP_M_ReferenceCounted` and not `CP_M_RefCounted`?
quamrana
@quamrana - changed the .h file name to C_M_RefCounted.h and the typedef to CPLAT::CP_M_RefCounted and viola! Thanks.
ML