[CLN-list] cln compile error

Bruno Haible bruno at clisp.org
Sat Oct 13 19:18:12 CEST 2007


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



More information about the CLN-list mailing list