1 |
Hello, |
2 |
|
3 |
After banging my head for a while over some strange results, I began |
4 |
to suspect GCC-4.5.2, the latest version in portage, was creating |
5 |
faulty code. |
6 |
|
7 |
It seems to a correct suspicion. |
8 |
|
9 |
What follows is a short C program that reproduces my particular problem, |
10 |
but there are likely many other situations where GCC could fail. The code |
11 |
may be a difficult for some people to follow but only the output is what |
12 |
actually matters. Simpler examples will certainly exist but I have not |
13 |
had the chance to develop them. |
14 |
|
15 |
The program is included here as both in-line text and as a file attachment |
16 |
(gcc_test.c). The problem is described below. |
17 |
|
18 |
------------------------------------ |
19 |
|
20 |
#include <stdio.h> |
21 |
#include <stdlib.h> |
22 |
|
23 |
int main(void) |
24 |
{ |
25 |
int n; |
26 |
double x; |
27 |
unsigned long int arg; |
28 |
unsigned long int *px = (unsigned long int*)&x; |
29 |
|
30 |
x=0.0; n=0; arg=0x4010000000000000; |
31 |
while(n<5) |
32 |
{ |
33 |
|
34 |
printf("%lx %g\n",arg, x); |
35 |
|
36 |
*px=arg; |
37 |
|
38 |
printf("%lx %g\n\n",arg, x); |
39 |
n++; arg=arg+0x0010000000000000; |
40 |
} |
41 |
|
42 |
exit(0); |
43 |
} |
44 |
|
45 |
------------------------- |
46 |
|
47 |
What this code does is not very important (it uses pointers to enter |
48 |
hexadecimal values into a floating point variable within a short loop). |
49 |
The output is what matters. |
50 |
|
51 |
Compiling with "gcc -O2 -march=native -o gcc_test gcc_test.c" |
52 |
produces this output: |
53 |
|
54 |
Loop: 0 |
55 |
Val = 4010000000000000, X before = 0 |
56 |
Val = 4010000000000000, X after = 0 --> X should be 4!!! |
57 |
|
58 |
Loop: 1 |
59 |
Val = 4020000000000000, X before = 0 |
60 |
Val = 4020000000000000, X after = 4 |
61 |
|
62 |
Loop: 2 |
63 |
Val = 4030000000000000, X before = 4 |
64 |
Val = 4030000000000000, X after = 8 |
65 |
|
66 |
The printf statements are included before and after the variable, x, |
67 |
is assigned a value. Notice how in the first iteration of the loop |
68 |
the x variable does *not* get assigned a value. The value of x during |
69 |
the first iteration should be 4. |
70 |
|
71 |
The problem can be fixed by compiling the program with "O1" |
72 |
optimization: |
73 |
|
74 |
gcc -O1 -march=native -o gcc_test gcc_test.c |
75 |
|
76 |
Using "O1" the output now becomes: |
77 |
|
78 |
Loop: 0 |
79 |
Val = 4010000000000000, X before = 0 |
80 |
Val = 4010000000000000, X after = 4 --> Now it works!!! |
81 |
|
82 |
Loop: 1 |
83 |
Val = 4020000000000000, X before = 4 |
84 |
Val = 4020000000000000, X after = 8 |
85 |
|
86 |
Loop: 2 |
87 |
Val = 4030000000000000, X before = 8 |
88 |
Val = 4030000000000000, X after = 16 |
89 |
|
90 |
This is now the correct output. In the first iteration the X variable |
91 |
is assigned the proper value. |
92 |
|
93 |
For anyone who wants to try to duplicate these results, please feel |
94 |
free to do so. |
95 |
|
96 |
So I will have to conclude that GCC-4.5.2 has serious problems. |
97 |
This kind of erroneous behavior could appear anywhere. |
98 |
|
99 |
Frank Peters |