https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90161

            Bug ID: 90161
           Summary: GCC does not always dllexport constexpr member
                    variables in C++17 mode
           Product: gcc
           Version: 8.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: m101010a at gmail dot com
  Target Milestone: ---

$ cat x.cpp
struct __attribute__((dllexport)) foo {
        static constexpr int i = 3;
};
constexpr int foo::i;
$ cat y.cpp
struct __attribute__((dllimport)) foo {
        static constexpr int i = 3;
};
int main() {
        volatile auto v = &foo::i;
}
$ i686-w64-mingw32-g++ x.cpp -shared -o libx.dll
$ i686-w64-mingw32-g++ y.cpp -o y.exe -L. -lx
$ rm -f libx.dll y.exe
$ i686-w64-mingw32-g++ -std=c++17 x.cpp -shared -o libx.dll
$ i686-w64-mingw32-g++ -std=c++17 y.cpp -o y.exe -L. -lx
/usr/lib/gcc/i686-w64-mingw32/8.3.0/../../../../i686-w64-mingw32/bin/ld:
/tmp/cc8oSAlw.o:y.cpp:(.text+0xf): undefined reference to `_imp___ZN3foo1iE'
collect2: error: ld returned 1 exit status
$ i686-w64-mingw32-g++ -v
Using built-in specs.
COLLECT_GCC=i686-w64-mingw32-g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/8.3.0/lto-wrapper
Target: i686-w64-mingw32
Configured with: /home/marc/.cache/aurman/mingw-w64-gcc/src/gcc/configure
--prefix=/usr --libexecdir=/usr/lib --target=i686-w64-mingw32
--enable-languages=c,lto,c++,objc,obj-c++,fortran,ada --enable-shared
--enable-static --enable-threads=posix --enable-fully-dynamic-string
--enable-libstdcxx-time=yes --with-system-zlib --enable-cloog-backend=isl
--enable-lto --enable-dw2-exceptions --disable-sjlj-exceptions --enable-libgomp
--disable-multilib --enable-checking=release
Thread model: posix
gcc version 8.3.0 (GCC) 


This difference is likely because in C++17, foo::i is an inline variable due to
being constexpr.  If there is a function in libx.dll which uses foo::i's
address, the address is exported properly and linking y.exe works fine.  This
works fine on Linux using the visibility attribute.  GCC appears to have
stopped exporting foo::i in GCC 7 (https://godbolt.org/z/yatDtS).

Reply via email to