Re: Strict aliasing problem in gcc 4.4.4

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/21/2010 03:08 PM, Andy Gibbs wrote:
> 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?

This is going to be hard.  Your library is based on the assumption that

struct point
 {
 double x, y;
 };

and

double pts[2];

have exactly the same memory layout, and that there is no padding, and
that pointers to them can be aliased.  Your question is more or less
equivalent to asking how to disable strict aliasing without
-fno-strict-aliasing.  I can't think of any way to solve this other
than fixing the code.  There's no legal way that you can cast a
pointer to a scalar to a pointer to some struct type.

Andrew.




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux