Dear GCC folks: I'm having a problem with GCC 2.95.3 that appears to be a compiler bug. It seems to be optimizing out inlined function code with side effects, and is related to binding a non-const pointer to a const pointer reference function parameter. The problem only happens with optimization on, and goes away with -O0.
I assume this must be known problem, but I'm having a hard time finding a patch to fix it. It is not an option at this time to upgrade to a newer compiler version, but we are planning to do that in the future. Below is the test program and output. I really appreciate any help you can give. Thanks in advance, --Ray ----------------------- #include <iostream> #include <iomanip> #include <string.h> typedef unsigned char byte; inline unsigned unpack2 (const byte *&data) { unsigned val = data[0] << 8 | data[1]; data += 2; return val; } inline unsigned unpack2 (const byte *&data, unsigned &count) { unsigned val = data[0] << 8 | data[1]; data += 2; count -= 2; return val; } /* inline unsigned unpack2 (byte *&data) { unsigned val = data[0] << 8 | data[1]; data += 2; return val; } inline unsigned unpack2 (byte *&data, unsigned &count) { unsigned val = data[0] << 8 | data[1]; data += 2; count -= 2; return val; } */ void extractInfo (byte *&data, unsigned &datalen, unsigned &f1, unsigned &f2) { cout << "data = " << data << ", datalen = " << datalen << endl; f1 = unpack2 (data, datalen); cout << "data = " << data << ", datalen = " << datalen << endl; byte *peek = data; //const byte *peek = data; // **** Adding "const" works around the compiler problem **** // Another work-around is to uncomment the non-const f1 of unpack2() above unsigned tmp = datalen; cout << "peek = " << peek << ", tmp = " << tmp << endl; (void) unpack2 (peek, tmp); // skip over irrelevant field cout << "peek = " << peek << ", tmp = " << tmp << endl; (void) unpack2 (peek, tmp); // skip over irrelevant field cout << "peek = " << peek << ", tmp = " << tmp << endl; unsigned xlen = unpack2 (peek, tmp); cout << "peek = " << peek << ", tmp = " << tmp << endl; f2 = xlen; } int main(int, char**) { byte *x = "0123456789"; unsigned len = strlen(x); unsigned fld1, fld2; extractInfo (x, len, fld1, fld2); cout << "x = " << x << endl; cout << "len = " << len << endl; cout << "fld1 = " << hex << fld1 << dec << endl; cout << "fld2 = " << hex << fld2 << dec << endl; return 0; } ----------------------- $ gcc-2.95.3-glibc-2.1.3/i686-unknown-linux-gnu/bin/i686-unknown-linux-gnu-g++ -O0 -W -Wall -o foo foo.cpp $ ./foo data = 0123456789, datalen = 10 data = 23456789, datalen = 8 peek = 23456789, tmp = 8 peek = 456789, tmp = 6 peek = 6789, tmp = 4 peek = 89, tmp = 2 x = 23456789 len = 8 fld1 = 3031 fld2 = 3637 $ gcc-2.95.3-glibc-2.1.3/i686-unknown-linux-gnu/bin/i686-unknown-linux-gnu-g++ -O2 -W -Wall -o foo foo.cpp $ ./foo data = 0123456789, datalen = 10 data = 23456789, datalen = 8 peek = 23456789, tmp = 8 peek = 23456789, tmp = 6 peek = 23456789, tmp = 4 peek = 23456789, tmp = 2 x = 23456789 len = 8 fld1 = 3031 fld2 = 3233