>Submitter-Id: net >Originator: James Jurach >Organization: FundsXpress >Confidential: no >Synopsis: static const int optimization fails in conditional expressions >Severity: serious >Priority: medium >Category: c++ >Class: sw-bug >Release: 3.0.3 20011209 (Debian prerelease) (Debian testing/unstable) >Environment: System: Linux mabel 2.2.19 #2 Thu Sep 6 14:51:54 CDT 2001 i686 unknown Architecture: i686
host: i386-pc-linux-gnu build: i386-pc-linux-gnu target: i386-pc-linux-gnu configured with: ../src/configure -v --enable-languages=c,c++,java,f77,proto,objc --prefix=/usr --infodir=/share/info --mandir=/share/man --enable-shared --with-gnu-as --with-gnu-ld --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-checking --enable-threads=posix --enable-java-gc=boehm --with-cpp-install-dir=bin --enable-objc-gc i386-linux >Description: When class members declared as static const int appear in conditional expressions, they are not properly optimized out. The compiler treats them as undefined variables, rather than integer literals. The result is the following error message: /tmp/ccruMK1G.o: In function `main': /tmp/ccruMK1G.o(.text+0x1b): undefined reference to `Foo::erf' /tmp/ccruMK1G.o(.text+0x29): undefined reference to `Foo::foo' collect2: ld returned 1 exit status This problem exists in 2.96, but does not exist in 2.95 and before. >How-To-Repeat: $ g++-3.0 -Wall -o condexpr condexpr.cpp /tmp/ccBleh7H.o: In function `main': /tmp/ccBleh7H.o(.text+0x1f): undefined reference to `Foo::erf' /tmp/ccBleh7H.o(.text+0x29): undefined reference to `Foo::foo' collect2: ld returned 1 exit status $ -*- begin of condexpr.cpp -*- #include <iostream.h> class Foo { public: static const int erf = 0; static const int foo = 1; }; int main(int argc,char **argv) { cout << "foo: " << (argc%2 ? Foo::erf : Foo::foo) << endl; return 0; } -*- end of condexpr.cpp -*- >Fix: Type-casting the const int's appears to be a work around, albeit a wretched one for production code: cout << "foo: " << (argc%2 ? (int)Foo::erf : (int)Foo::foo) << endl;