Hello!
I think it is MAYBE_INLINE hack.
Why do you think that it is related to MAYBE_INLINE?
See this message: http://www.ginac.de/pipermail/ginac-list/2003-November/000434.html
Why do you think MAYBE_INLINE is a hack? I don't see how it would violate ISO C++.
As you've pointed out yourself,
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.
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.
So far so good.
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.
Not exactly. g++ decided that inline zerop(cln::cl_I const&) is too complicated to be inlined and emitted it out-of-line. Such functions are placed into the .text<mangled name of the function> section (on ELF it would be placed into .text section as a weak symbol). We end up with duplicate symbols: one in the .text section (extern bool zerop), and another one in the .text<mangled name of the function> section. Linker reports the error, and that is it. This sutiation is impossible with standard-compliant code, since the function will be either inline in all translation units (there will be one symbol in the .text<mangled name of the function> section), or non-inline (there will be one symbol in the .text section). On ELF platform the linker discards weak symbol[s] with no error, so MAYBE_INLINE hack [kind of] works there.
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...
I doubt it. MAYBE_INLINE or not, but the compiler emits this function out-of-line anyway -- on Linux there is a weak symbol for cln::zerop(cln::cl_I const&) inside cl_I_ring.o, and there is .text$_ZN5zeropERKNS_4cl_IE section on woe32. Best regards, Alexei. -- All science is either physics or stamp collecting.