I have project I'm porting from from 32 bit Windows to 64 bit, which includes code that can be simplified as follows:
void FuncA(double &x)
{
x = 0;
}
void FuncB(double *x)
{
*x = 0;
}
#pack(1)
struct
{
char c;
double x;
} MyStruct;
#pack();
void MyFunc()
{
MyStruct M;
FuncA(M.x); // This is OK
FuncB(&M.x); // This generates a warning C4366
}
When compiling under VS2010 SP1 targeting 64 bit, calling FuncB
with a member of a packed struct generates the following warning:
warning C4366: The result of the unary '&' operator may be unaligned
Whereas calling FuncA
does not. I would have thought that both cases would have compiled down to pretty much the same code. Are references somehow safer from alignment problems than the equivalent pointer? Or is it that MSVC is simply not issuing a warning where it should? The project requires the struct packing is maintained, so my choices are to either change FuncB
to
void FuncB(__unaligned double *x)
{
*x = 0;
}
or to simply use FuncA
in all such cases. The latter would be preferable as it is more portable, but I'm wondering is it going to work or is the lack of a warning in the reference case simply a shortcoming in the compiler?
Edit: The Microsoft help entry for this error is here. The __unaligned help suggests that failing to heed this warning will cause exceptions to be thrown on Itanium processors. Further trawling around MSDN suggests there may be issues surrounding unaligned references. While this may not cause problems for my current users, if the Itanium architecture becomes more widely used in future, I could be setting up a support nightmare. Plan is now to add specific wrappers for all the functions that use the packed structures, to avoid the pointers and the __unaligned keyword.