[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