http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50028
Summary: Ternary operator and static const member variable Product: gcc Version: 4.6.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: protocolo...@gmail.com Created attachment 24960 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24960 Preprocessor intermediate file Problem: The following code: #include <stdlib.h> #include <stdio.h> class test { public: static const unsigned char OPT1=27; static const unsigned char OPT2=72; }; int main() { unsigned cond=rand(); unsigned value1, value2; if(cond) value1=test::OPT1; else value1=test::OPT2; value2=cond?test::OPT1:test::OPT2; printf("%d %d\n", value1, value2); return 0; } Compiles w/o warnings with: $ g++ -Wall -Wextra -o testO2 -g -O2 test.cc But fails to compile/link with: $ g++ -Wall -Wextra -o testO2 -g -O0 test.cc /tmp/ccwLVGVv.o: In function `main': /home/asier/desarrollo/tmp/gcc_poc/test.cc:16: undefined reference to `test::OPT1' /home/asier/desarrollo/tmp/gcc_poc/test.cc:16: undefined reference to `test::OPT2' collect2: ld returned 1 exit status Analysis: The problem only happens in the ternary operator, but not in the if statement that precedes it. Compiler is not substituting class constants in conditional operator so that compilation unit gets a reference to a test::OPT1 and test::OPT2 in the .rodata section (that actually does not exist). See attacked preprocesor output and intermediate assembly code. Compilers tested: GCC 4.3 Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.5-4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.3.5 (Debian 4.3.5-4) GCC 4.4 Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.4.5 (Debian 4.4.5-8) GCC 4.6 Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.1-4' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/x86_64-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib/x86_64-linux-gnu --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.6.1 (Debian 4.6.1-4) System info: Linux frito 2.6.32-5-amd64 #1 SMP Mon Mar 7 21:35:22 UTC 2011 x86_64 GNU/Linux