Multiple definition of static constexpr data member with C++11 and 17

Jonathan Wakely jwakely.gcc@gmail.com
Mon Aug 16 09:52:20 GMT 2021


On Mon, 16 Aug 2021 at 10:37, wpty wpty via Gcc-help
<gcc-help@gcc.gnu.org> wrote:
> My questions are:
> 1. Is mixing C++11 and C++17-compiled object files like I do supported by
> GCC?

Yes.

> 2. If it is supported, then is something wrong with my code? The library is
> compiled using C++11 and the C++11 standard requires that explicit
> definition of constexpr static members are provided if they are odr-used
> (which it is in my case), so lib.cpp has a definition of A::x. But if I try
> to link the resulting object file with another object file that was
> compiled using C++17, the linker gives a multiple definition error.

In C++17 the declaration in the class body is an inline variable, so
GCC emits a definition using the STB_GNU_UNIQUE binding, which means
that multiple definitions are allowed and the linker will only keep
one. However, that seems to only work if all definitions use that
binding. In this case, the C++11 lib.o object has a non-weak
non-STB_GNU_UNIQUE definition, which cannot be merged with the
STB_GNU_UNIQUE definition.

Clang's weak definition can be ignored by the linker in favour of the
non-weak definition from the C++11 object.

I'm not sure if GCC should change, or if the linker should be changed
to permit a single non-weak non-UNIQUE definition to be merged with
zero or more UNIQUE definitions. As a workaround you can compile the
C++17 code with -fno-gnu-unique so that GCC uses a weak symbol, but
that isn't a good solution in general (the unique binding exists for
good reasons).

Please report this to GCC's bugzilla, with the reproducer, thanks.


More information about the Gcc-help mailing list