http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760



--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-03-28 
17:19:06 UTC ---

(In reply to comment #10)

> But the function actually IS defined,



No it isn't! Please read my answer again carefully.



The function that gets called is 



template<class T> void func (const T &a, nam::binbuffer &b);



and NOT



template<class T> void func(const seco::holder<T> &a, nam::binbuffer &b)

{ func(*a.fun, b); }



These are not the same function, and the first one is NOT defined.





> because the call func(foo,b) works.



That comes *after* the relevant function is defined, so name lookup finds it.



> Yes

> it is not defined early enough maybe. But the linker is run after the 
> compiler.



Irrelevant. The call to func(*a.wombat, b) finds a function template that is

not defined. The compiler generates a reference to a particular function, the

linker can't decide to link it to a different function just because you think

they're similar.





> How can the linker differentiate about when something is implemented? doesn't

> it just look for the symbol and if it is there, then it is there?



Because the call doesn't use the function you think it does!





> as mentioned in my post 2013-03-28 08:27:34 UTC the signature of the missing

> implementation is exactly the same in the error message if you leave out the

> template definition than if you do the line that you call invalid C++.



No, they are *not* the same, try using 'nm' to see they are different symbols:



                 U _Unwind_Resume

0000000000000000 W

_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE

                 U _Z4funcIN4seco6holderIiEEEvRKT_RN3nam9binbufferE

0000000000000000 W _Z4funcIiEvRKN4seco6holderIT_EERN3nam9binbufferE

0000000000000000 T _Z4funcIiEvRKT_RN3nam9binbufferE

                 U __gxx_personality_v0

000000000000000e T main



The missing definition is



                 U _Z4funcIN4seco6holderIiEEEvRKT_RN3nam9binbufferE



and the defined one is:



0000000000000000 W _Z4funcIiEvRKN4seco6holderIT_EERN3nam9binbufferE



THESE ARE NOT THE SAME SYMBOL!



Demangled, the names are:



                 U void func<seco::holder<int> >(seco::holder<int> const&,

nam::binbuffer&)

0000000000000000 W void func<int>(seco::holder<int> const&, nam::binbuffer&)



THESE ARE NOT THE SAME SYMBOL!





> So maybe the linker output should show more detail. The linker sais that an

> implementation is missing, which is NOT missing.



You're wrong. Look at the symbols.





> so maybe there is some

> additional clue that the linker could display here? is there some hidden

> additional information in the function signature somehow?



It's not hidden, it's right there in the signature but you're refusing to read

it:



x.C:11: undefined reference to

 `void func<seco::holder<int> >(seco::holder<int> const&, nam::binbuffer&)'

            ^^^^^^^^^^^^^^^^^

Look at the template argument list. Are you sure you defined it?

Look at the symbols again, with whitespace added to help:



U void func<seco::holder<int> >(seco::holder<int> const&, nam::binbuffer&)

W void func<int>               (seco::holder<int> const&, nam::binbuffer&)



Can you see what's different yet?



> the section about name lookup changes talks about the -fpermissive option 
> which

> should reactivate the old behaviour. but that does not work.



I didn't say -fpermissive would work, but the text describes how name lookup

only finds names that are visible at the point of definition, or can be found

by ADL at the point of instantiation.



> anyway... what could be a workaround? as mentioned earlier I cannot do a

> forward declaration.



It's not GCC's job or my job to fix your code, please try somewhere more

suitable like stackoverflow.com

Reply via email to