This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Why warning on static local variables ... ?


Munagala V S Ramanath <ram@netcom.com> writes:

> tmp1.C: In function `struct A<int,8> Mul<A<int,8>>(const struct A<int,8> &, const struct A<int,8> &)':
> tmp1.C:51: warning: sorry: semantics of inline function static data `int const n' are wrong (you'll wind up with multiple copies)

AFAIK, this occurs only on some targets that do not support ELF weak
symbols, or something like that.  It does not occur on Solaris 2.[56], 
for instance, but it does occur in SunOS 4.1.3.  You can only notice
this problem if the inline function is instantiated in two different
compilation units.

> PROBLEM 2: As can be seen from the above program output, it seems to
>    be invoking the wrong constructor [A(int) instead of A(&A)] for the
>    declaration like: B f3( Mul<B>( f1, f1 ) );
>    Is there some default rule that I'm overlooking or is it a bug ?

The compiler is allowed to optimize away such copy-constructor call.
Instead of copy-constructing the object returned by Mul<B> into f3 and
f4, egcs arranges that Mul<B> constructs f3 and f4 directly, in-place.

> PROBLEM 3: If the "#define WORKS" is commented out, it gets all
>    confused about instantiationg operator<<; even adding an explicit
>    instantiation does not help. Here is the initial part of the list of
>    diagnostics I get:

> ========================================================================
> tmp1.C: In function `class ostream & operator <<<char[15]>(class ostream &, const char (&)[15])':
> tmp1.C:66: request for member `val' in `a', which is of non-aggregate type `char[15]'
> tmp1.C:66: `char[15]' is not an aggregate type

The problem is that the ostream class (which should be a
specialization of template basic_ostream, but that's another story)
provides member operators for outputting `char *' and `const char *'
(these operators should have been global functions instead of member
ones, BTW), but not for `char[]' and `const char[]'.  Since a string
literal has type `char [n]' (according to the C++ Standard, it should
be `const char [n]', but that's yet another story), your global
operator << is a exact match that requires an identity conversion
(i.e., no conversion), whereas the member function is an exact match
that requires an lvalue-transformation (array-to-pointer conversion).
Hence, your global operator<< is a better match, so it is preferred.

As a rule of thumb, don't ever define such a general template for
stream classes; overloading operator<< for the particular type or
template class you have defined is a much safer approach.

-- 
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]