Subject: Re: C++ problem: building "pkgsrc/audio/daapd" with GCC 4.x
To: None <tech-pkg@NetBSD.org>
From: Matthias Scheler <tron@zhadum.org.uk>
List: tech-pkg
Date: 07/03/2006 01:45:29
In article <e85kvl$kji$2@colwyn.zhadum.org.uk>,
	tron@zhadum.org.uk (Matthias Scheler) writes:
> In article <20060701082740.GB360@britannica.bec.de>,
> 	joerg@britannica.bec.de writes:
>>> void TypeRegistry::registerVar( const Var* var ) {
>>>         varMap[var->name] = var;
>>>         container << Tag( 'mdcl' ) <<
>>>                 Tag( 'mcnm' ) << var->mnemonic  << end <<
>>>                 Tag( 'mcna' ) << var->name      << end <<
>>>                 Tag( 'mcty' ) << (u16)var->type << end <<
>>>         end;
>>> }
>> 
>> I guess: TypeRegistry is a template class ...
> 
> It is indeed.
> 
>> ... and end doesn't depend on the template parameter.
> 
> Shouldn't TypeRegistry::End work in that case? Unfortunately it doesn't.

I found the problem. "container" is an object of the "TagOutput" class
which is defined like this:

class TagOutput {
public:
[...]
        inline TagOutput& operator << ( TagOutput& (*func)( TagOutput& )) {
                return( func( *this ));
        }

        friend inline TagOutput& end( TagOutput& x ) {
                return( x.closeTag());
        }
[...]

So the above code is basically trying to pass the friend function end to
the << operator of "TagOutput" class. GCC 4.1.x does however not allow
such friend declaration anymore. Quoting from the list of changes
in GCC 4.1.x:

C++

    * ARM-style name-injection of friend declarations is no longer the default.
      For example:

                struct S {
                  friend void f();
                };

                void g() { f(); }

      will not be accepted; instead a declaration of f will need to be present
      outside of the scope of S. The new -ffriend-injection option will enable
      the old behavior.

	Kind regards

-- 
Matthias Scheler                                  http://scheler.de/~matthias/