Mailing List Archive


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

[tlug] Portability of Misaligned Data Access . . . . . . . (was Re: issues with format of double (or IEEE754))



Portability is a good thing. 

I love stuff like: 

   (*(double *)&result_normal_plus[2])

but Stephen makes a good point about alignment. 
It makes me think about the portability of some of the stuff 
I've written. Most runs on Intel trash, which seemingly 
tolerates misaligned data, but such programs might puke 
when running on non x86 family CPUs. 

"Stephen J. Turnbull" wrote:

> >>>>> "Michal" == Michal Hajek <hajek1@example.com> writes:
>     Michal> where presult is a pointer to double, eg. defined as:
>     Michal> double *presult;
> 
>     Michal> The problem is that if I print the number:
> 
>     Michal> printf("*presult: %.12f \n",*presult);
> 
> Well, if you're not getting bus errors, I guess alignment doesn't
> matter.  This kind of casting is normally an excellent way to get into
> real trouble, though.

There was a discussion at a recent lunch about this. 
Another bread breaker was talking about how x86 CPUs would 
tolerate misaligned data, but with a whopping speed 
penalty. 

(Michal, the kind of speed penalty referred to is 
still insignificant to your problem.)

You raised a good point about the portability of accessing 
misaligned data. 

So, to avoid alignment issues, cajole the rx buffer 
so that result_normal_plus+2 is aligned for a double 
(which is much too tricky), or copy the data into an 
obviously aligned place (much better, no tricks). 

   double foo; 
   int i;

   for (i=0;i<sizeof(foo);i++)
      (*(unsigned char *)&foo)[i]=(*(unsigned char *)(result_normal_plus+2))[i];

or

   double foo;
   unsigned char *s=(unsigned char *)&foo;
   unsigned char *t=(unsigned char *)(result_normal_plus+2);
   int i;

   for (i=0;i<sizeof(foo);i++)
      *s++=*t++;

then you can access foo without worrying about alignments issues
(except perhaps for sizeof reporting a padded value 
and reading too much from possibly unpadded (result_normal_plus+2), 
causing a segmentation fault). 

Afterwards, one could do Stephen's result_normal_plus[2]='\0' 
for the two characters. 

Aligning the data on a nice boundary is a separate issue 
from what format (IEEE 754 or not) a double is in. 

We've probably overwhelmed Michal by now. 

Jim



Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links