Adriaan de Groot wrote:
> See 
> http://people.fruitsalad.org/adridg/bobulate/index.php?/archives/578-Why-kcm-modules-are-weird-under-Solaris.html
>  
> for a writeup; this is why kcm's don't load right in some cases, because 
> multiple calls to registerPlugin() call the constructor of the first plugin 
> registered repeatedly instead of the consuctor of the new plugin. Example 
> code is included.
> 
> I have a workaround, which is in Dude already. So kdelibs from r.1915 or so 
> and later will be ok. Comments on the validity of the bug welcome.

CC -library=stlport4 -o test -verbose=template +w2 
template-function-example.cc

"template-function-example.cc", line 75: Warning: should not initialize 
a non-const reference with a temporary.
"template-function-example.cc", line 75: Warning: should not initialize 
a non-const reference with a temporary.
"template-function-example.cc", line 75: Warning: should not initialize 
a non-const reference with a temporary.
"template-function-example.cc", line 75: Warning: should not initialize 
a non-const reference with a temporary.
"template-function-example.cc", line 84: Information: Instantiating 
foo<A>(int, object*(*)(int)).

"template-function-example.cc", line 77: Warning: Cannot cast from 
object*(*)(int) to void*.

"template-function-example.cc", line 57: Information: Instantiating 
aFunction<A>(int).
"template-function-example.cc", line 85: Information: Instantiating 
foo<B>(int, object*(*)(int)).

"template-function-example.cc", line 86: Information: Instantiating 
foo<E>(int, object*(*)(int)).
"template-function-example.cc", line 77: Warning: Cannot cast from 
object*(*)(int) to void*.

(Some trimmed). The void* casts are harmless, though not strictly legal. 
The non-const ref from temporary is dodgy, and produces nasty leaks:
Actual leaks report    (actual leaks:            3  total size: 
  3 bytes)
   Total     Num of  Leaked     Allocation call stack
   Size      Blocks  Block
                     Address
==========  ====== =========== =======================================
          1       1  0x8062e98  operator new<-aFunction<-foo<-main
          1       1  0x8062eb8  operator new<-aFunction<-foo<-main
          1       1  0x8062ed8  operator new<-aFunction<-foo<-main


The compiler says it is instantiating the objects that you want. With nm 
  I see (with OK)

nm -C test | grep foo 

[94]    | 134550384|     109|FUNC |GLOB |0    |10 
|__type_0*foo<A>(int,object*(*)(int))
[127]   | 134550544|     109|FUNC |GLOB |0    |10 
|__type_0*foo<B>(int,object*(*)(int))
[122]   | 134550656|     109|FUNC |GLOB |0    |10 
|__type_0*foo<E>(int,object*(*)(int))

and (without OK)
nm -C test | grep foo 

[109]   | 134549776|      95|FUNC |GLOB |0    |10     |void 
foo<A>(int,object*(*)(int))
[100]   | 134549920|      95|FUNC |GLOB |0    |10     |void 
foo<B>(int,object*(*)(int))
[115]   | 134550016|      95|FUNC |GLOB |0    |10     |void 
foo<E>(int,object*(*)(int))

(I'm not sure what the __type_0* is)

Now, having instantiated 3 foo(int,object*(*)(int)) functions, I'm not 
sure how the compiler is supposed to choose between the overloads given 
the calls foo(0), foo(1) and foo(2). It seems to be resolving to the 
first. Look what happens with

         foo<E>(2);
         foo<A>(0);
         foo<B>(1);

I don't either understand why this changes when you alter the return 
type - that is not supposed to play a role in function overload resolution.

A+
Paul


Reply via email to