Hi all,
I have a question regarding strict aliasing and GCC 4.4.4. It has come to
light in the recompilation of a third-party library that I'm using. I've
created a small example of the type of code that can demonstrate the
problem:
#include <stdio.h>
struct point
{
point(double x, double y)
: x(x), y(y) { }
double x, y;
};
point function1(point* array, int len)
{
/* do some initialisation on array */
for (int i = 0; i < len; i++)
{
array[i].x = i;
array[i].y = i * 1.25;
}
return point(-1.0, -2.0);
}
void function2(double* pts, int len)
{
for (int i = 0; i < len; i++)
printf("%i %f\n", i, pts[i]);
}
void do_ops(double* pts)
{
point* points = (point*)pts;
points[0] = function1(&points[1], 3);
}
int main(int, char**)
{
double pts[8];
#ifdef INLINE
point* points = (point*)pts;
points[0] = function1(points+1, 3);
#else
do_ops(pts);
#endif
function2(pts, 8);
return 0;
}
To give some context, 'function1' and 'function2' are methods inside this
3rd party library (actually in the code above they are simplified
approximations, but keeping the same function prototypes). A segment of
code from elsewhere inside the library calls this function in a way similar
to the following:
double pts[8];
point* points = (point*)pts;
points[0] = function1(points*1, 3);
function2(pts, 8);
The code above then puts all this together. If I compile this code in any
of the following ways:
g++ test.cpp -Wall -Werror -o test
g++ test.cpp -Wall -Werror -o test -DINLINE
g++ test.cpp -Wall -Werror -o test -finline-functions
g++ test.cpp -Wall -Werror -o test -O2
then all well and good. The code compiles and runs without error.
However, if I compile in one of the following ways (which is my aim):
g++ test.cpp -Wall -Werror -o test -O2 -DINLINE
g++ test.cpp -Wall -Werror -o test -O2 -finline-functions
g++ test.cpp -Wall -Werror -o test -O3
Then I get this:
cc1plus: warnings being treated as errors
test.cpp: In function 'int main(int, char**)':
test.cpp:41: error: dereferencing pointer 'points' does break
strict-aliasing rules
test.cpp:40: note: initialized from here
My question is, how can I fix the code to solve this error? The error is in
the assignment to points[0], I believe.
I don't want to specify -fno-strict-aliasing nor remove the -Werror since
this will have a impact on the whole library. I also cannot change how
'function1' and 'function2' operate, since they are used in multiple
locations. I can however change the line that does the cast from double* to
point* prior to the call to 'function1'.
But, I can't find the correct way to handle this cast. I've read about
casting through a union (e.g. at
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html),
but I can't seem to get it to work. This seems to me to be the best way to
tackle it, unless someone can suggest another way. I expect it is something
really simple that I've overlooked.
Please, could anyone help me with this?
Thanks
Andy