[GiNaC-devel] [SCM] GiNaC -- a C++ library for symbolic computations branch, master, updated. release_1-4-0-708-ga569b474
Richard B. Kreckel
kreckel at in.terlu.de
Wed Feb 3 15:59:52 CET 2021
Alexey,
Is that patch really correct?
On 06.01.21 16:45, Richard B. Kreckel via GiNaC-devel wrote:
> commit c3195f0b5a7ac9fdbfdd04e5f4acf6a836063de0
> Author: Alexey Sheplyakov <asheplyakov at altlinux.org>
> Date: Wed Jan 6 11:20:46 2021 +0400
>
> Avoid multiple definitions of `lst::info` (MinGW compile fix)
>
> [55/59] Linking CXX shared library bin/libginac.dll
> FAILED: bin/libginac.dll ginac/libginac.dll.a
> [skipped long list of object files]
> /usr/bin/x86_64-w64-mingw32-ld: ginac/CMakeFiles/ginac.dir/lst.cpp.obj: in function `GiNaC::ptr<GiNaC::basic>::~ptr()':
> /home/asheplyakov/work/sw/ginac/_build_w64/../ginac/container.h:150: multiple definition of `GiNaC::container<std::__cxx11::list>::info(unsigned int) const'; ginac/CMakeFiles/ginac.dir/integration_kernel.cpp.obj:/home/asheplyakov/work/sw/ginac/_build_w64/../ginac/container.h:116: first defined here
>
> integration_kernel.cpp makes use of GiNaC::lst without including the `lst.h`
> header. That's possible since there's a typedef in `registrar.h` (included
> by virtually all GiNaC sources) and a defintion in `container.h` (included
> via `add.h` -> `expairseq.h` -> `indexed.h` -> `exprseq.h`), so the compiler
> can instantiate container<std::list>. However the explicit specialization
> of `lst::info` is not available (in integration_kernel.cpp). This violates
> 17.8.3.6 [templ.expl.spec] which demands
>
> If a template, a member template or a member of a class template is
> explicitly specialized then that specialization shall be declared before
> the first use of that specialization that would cause an implicit
> instantiation to take place, in every translation unit in which such
> a use occurs; no diagnostic is required. If the program does not provide
> a definition for an explicit specialization and either the specialization
> is used ina way that would cause an implicit instantiation to take place
> or the member is a virtual member function, the program is ill-formed,
> no diagnostic required.
>
> On ELF platforms libginac appears to link just fine despite having two
> instantiations of `lst::info` since the of them (in `integration_kernel.o`)
> is a weak symbol:
>
> $ find ginac -type f -name '*.o' | xargs -n 1 nm --print-file-name --defined | c++filt | grep -e 'list>::info('
> ginac/CMakeFiles/ginac.dir/integration_kernel.cpp.o:0000000000000000 W GiNaC::container<std::__cxx11::list>::info(unsigned int) const
> ginac/CMakeFiles/ginac.dir/lst.cpp.o:0000000000000000 T GiNaC::container<std::__cxx11::list>::info(unsigned int) const
>
> so the linker discards the wrong instantiation of `lst::info` method.
> However on MinGW there are no weak symbols (in ELF sense):
>
> $ find ginac -type f -name '*.obj' | xargs -n 1 x86_64-w64-mingw32-nm --print-file-name --defined | c++filt | grep -e 'list>::info('
> ginac/CMakeFiles/ginac.dir/lst.cpp.obj:0000000000000010 T GiNaC::container<std::__cxx11::list>::info(unsigned int) const
> ginac/CMakeFiles/ginac.dir/integration_kernel.cpp.obj:0000000000000000 T GiNaC::container<std::__cxx11::list>::info(unsigned int) const
>
> Hence the above multiple definition error.
>
> To avoid the problem #include "lst.h" (so explicit specialization is available).
> While at it explicitly instantiate lst::info method in lst.cpp
>
> A better solution would be to remove declaration of lst from registrar.h,
> but that's too disruptive since GiNaC uses lst a lot: subs, unarchive, etc.
I came across it because clang++ now complains:
lst.cpp:41:37: warning: explicit instantiation of 'info' that occurs
after an explicit specialization has no effect
[-Winstantiation-after-specialization]
Wouldn't it be sufficent to include "lst.h" in "integration_kernel.cpp"?
I must admit that I do not understand the rest of it.
All my best,
-richy.
--
Richard B. Kreckel
<https://in.terlu.de/~kreckel/>
More information about the GiNaC-devel
mailing list