[CLN-list] MAYBE_INLINE and link errors.
Alexei Sheplyakov
varg at theor.jinr.ru
Mon Oct 15 17:34:55 CEST 2007
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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/cln-list/attachments/20071015/b5391b76/attachment.pgp
More information about the CLN-list
mailing list