Alexei Sheplyakov wrote:
Hopefully some Cygwin expert can have a look into this. On Linux, I geat a weak symbol "W" for cln::zerop(cln::cl_I const&) inside cl_I_ring.o. I don't quite comprehend what generates it,
I think it is MAYBE_INLINE hack.
Why do you think that it is related to MAYBE_INLINE? cln/src/integer/elem/cl_I_zerop.c does not use MAYBE_INLINE. Why do you think MAYBE_INLINE is a hack? I don't see how it would violate ISO C++. Chris Bouchard's error message was this: ../src/.libs/libcln.a(cl_I_ring.o):cl_I_ring.cc:(.text$_ZN5zeropERKNS_4cl_IE[cln::zerop(cln::cl_I const&)]+0x0): multiple definition of `cln::zerop(cln::cl_I const&)' ../src/.libs/libcln.a(cl_I_zerop.o):cl_I_zerop.cc:(.text+0x0): first defined here So let's look at the two compilation units cl_I_zerop.cc and cl_I_ring.cc. cl_I_zerop.cc contains this code: ------------------------------------------------------------------------- extern bool zerop (const cl_I& x); // from <cln/integer.h> bool zerop (const cl_I& x) { return inline_zerop(x); } ------------------------------------------------------------------------- That it leads to an exported symbol cln::zerop in the object file, is fine. cl_I_ring.cc contains this code: ------------------------------------------------------------------------- extern bool zerop (const cl_I& x); // from <cln/integer.h> inline bool zerop (const cl_I& x) // from cl_I.h { return x.word == cl_combine(cl_FN_tag,0); } static cl_number_ring_ops<cl_I> I_ops = { cl_I_p, equal, zerop, ... }; ------------------------------------------------------------------------- You can see that it leads to a symbol cln::zerop in the object file, in the segment .text$_ZN5zeropERKNS_4cl_IE[cln::zerop(cln::cl_I const&)] To me, that indicates that g++ has tried to avoid a collision with the cln::zerop symbol in the .text segment, but somehow the linker does not treat the segments that way. C++ inline functions are certainly tricky to compile, given that ISO C++ section 7.1.2.(4) says: "An inline function with external linkage shall have the same address in all translation units." And here the problem is that we take its address... But I must admit that CLN is outside the ISO C++ specification because it also says in 7.1.2.(4): "If a function with external linkage is declared inline in one transla- tion unit, it shall be declared inline in all translation units in which it appears" and CLN declares cln::zerop only inline in those compilation units that include "cl_I.h" (except cl_I_zerop.cc), not in all other compilation units. But this is necessary for good inlining... Bruno