From Bugzilla Helper: User-Agent: Mozilla/4.72 [en] (X11; U; Linux 2.2.14-5.0 i686) Description of problem: Incorrect code is generated when the following program is compiled with -O2 or -O3, it seems the assignment is optimized out: #include <stdio.h> typedef long long jlong; int * _value; int _size; jlong ar[100]; inline void put_int2r(int *from, int *to) { *(to++) = from[1]; *(to ) = from[0]; } inline void put_int2r(int *from, int *to, int& pos) { put_int2r(from, to + pos); pos += 2; } void put_long(jlong from, int *to, int& pos) { put_int2r((int *)&from, to, pos); } void push_long(jlong l) { put_long(l, _value, _size); } void main(void) { _size = 0; _value= (int *)ar; puts("This test program is to show a g++ compiler bug."); puts("The correct output should be '12345678,9abcdef0'"); puts("But if you compile this program with '-O2' or '-O3',"); puts("it will print wrong numbers."); puts("----------------------------------------------------"); puts("RESULT:"); push_long(0x123456789ABCDEF0); printf("%x,%x\n", _value[0], _value[1]); } Version-Release number of selected component (if applicable): 2.96, 3.0.1 How reproducible: Always Steps to Reproduce: 1. g++ -O2 tstputlong.cpp 2. a.out 3. Actual Results: RESULT: 401b89e4,4009302c Expected Results: RESULT: 12345678,9abcdef0 Additional info: 1. "-O" can generate correct result 2. We have tested gcc 2.96-81, 2.96-95 and 3.0.1, all broken. 3.0.1 can't even compile this program with "-O0". 3. This bug can cause JDK crash since trash value is returned when we try to retrieve a previously stored pointer.
Your program has undefined behaviour, so compiler is free to do whatever it wants. Particularly you're doing invalid type punning. Read info gcc, description of -fstrict-aliasing. If you don't want to fix your code, the quick way around is using -fno-strict-aliasing, but far better is fixing the code, e.g. using unions.
Fine, and thank you very much for the pointer. But why can't gcc print a warning or something? It's not so uncommon to typecast pointers, is it? Besides, most people are not familiar with vague gcc options as -fstrict-aliasing. Yet it can cause very hard to track crashes. Note that this option is not even listed in the man page! Something needs to be done instead of just closing the bug, IMHO.
Plase search http://gcc.gnu.org/ml/gcc for strict-aliasing, you'll find there a lot about why is it the default, also discussions about warnings, etc. The man page for gcc is not the definite gcc documentation, unlike info gcc (that's common with other GNU packages), and actually it is not that important to list -fstrict-aliasing since it is the default at -O2 and above. This option has been the default in gcc 2.95 but was turned off before 2.95.2 was released because too many people moaned about unfixed software. The output of this was that there were several broken packages when we started working on 7.0 which we had to fix. Making the option the default is the only way how to make sure people fix their software. We have fixed all sources included in our distribution for aliasing problems, but we cannot fix JDK for you (unless you make it open source which would be a good thing IMHO). Also note that gcc 3.0 and above have -fstrict-aliasing as default too, so this is not something Red Hat specific. In the strict-aliasing discussions on gcc.org and other gcc mailing lists you can find e.g. grep patterns for searching for possibly dangerous code. And gcc is not definitely the only compiler out there which uses this optimization.