http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52069
Bug #: 52069 Summary: ARM: initialization of static member in template struct Classification: Unclassified Product: gcc Version: 4.5.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: thomas.bet...@rohde-schwarz.com main.cpp is linked with a shared library libtmpl.so which initializes a static member S<T>::id of a template struct. The expected outcome is that main() sees the initialized value of S<T>::id. When tmpl.cpp is compiled with optimization, though, the actual outcome is that main() sees an all-zeros value. The problem was observed with gcc-4.5.2, gcc-4.5.3, gcc-4.6.0, gcc-4.6.1, all built by crosstool-ng-1.13.2 for ARM (gcc-4.6.2 is not yet supported by crosstool-ng); the output of g++ -v for gcc-4.5.3 is included at the end of this text. I was not able to reproduce the problem for x86. The attached .tgz contains tmpl.h, tmpl.cpp, main.cpp as well as tmpl.ii, main.ii. I have compiled main.cpp and tmpl.cpp as follows: arm-armv6-linux-gnueabi-g++ -c -o main.o main.cpp arm-armv6-linux-gnueabi-g++ -c -O -o tmpl.o tmpl.cpp arm-armv6-linux-gnueabi-g++ -shared -Wl,-soname,libtmpl.so -o libtmpl.so tmpl.o arm-armv6-linux-gnueabi-g++ -o testbug main.o libtmpl.so I did the usual checks with -Wall -Wextra; there were no warnings or errors. The example is minimal in the sense that the problem does not occur when: * tmpl.cpp is compiled without optimization (it does not matter if main.cpp is compiled with or without optimization) * main.o is linked directly with tmpl.o, i.e., you cannot skip the shared library step * S<T>::id is initialized by an immediate value, not by a separate const * S<T>::id is an unsigned long, not a struct The problem also does not occur when you add a line "template struct S<T>;" before the initialization; this is our current workaround. I can't tell if this explicit instantiation is permitted or even required by the standard [I leave this question to the C++ gurus], but g++ does not complain either way, and at least it helps ... My impression from debugging was that the initialization is not correctly relocated. The symbol S<T>::id exists twice, once in the BSS section of libtmpl.so and once in the BSS section of main.o; without optimization, the symbol in main.o is initialized (as it should), and with optimization, the symbol in libtmpl.so is initialized. But that's just my 2ยข. The output of arm-armv6-linux-gnueabi-g++ -v is: Using built-in specs. COLLECT_GCC=/home/RSINT/betker/opt/arm-4.5.3/bin/arm-armv6-linux-gnueabi-g++ COLLECT_LTO_WRAPPER=/home/RSINT/betker/opt/arm-4.5.3/bin/../libexec/gcc/arm-armv6-linux-gnueabi/4.5.3/lto-wrapper Target: arm-armv6-linux-gnueabi Configured with: /home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/src/gcc-4.5.3/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-armv6-linux-gnueabi --prefix=/home/RSINT/betker/opt/arm-5.4.3 --with-sysroot=/home/RSINT/betker/opt/arm-5.4.3/arm-armv6-linux-gnueabi/sysroot --enable-languages=c,c++ --disable-multilib --with-arch=armv6 --with-fpu=vfp3 --with-pkgversion='crosstool-NG 1.13.2' --enable-__cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp --with-gmp=/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static --with-mpfr=/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static --with-mpc=/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static --with-ppl=/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static --with-cloog=/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static --with-libelf=/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++ -lm -L/home/RSINT/betker/tmp/crosstool-ng-1.13.2-arm-5.4.3/.build/arm-armv6-linux-gnueabi/build/static/lib -lpwl' --enable-threads=posix --enable-gold --with-local-prefix=/home/RSINT/betker/opt/arm-5.4.3/arm-armv6-linux-gnueabi/sysroot --disable-nls --enable-c99 --enable-long-long Thread model: posix gcc version 4.5.3 (crosstool-NG 1.13.2)