Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alignment 16 not respected when using auto keyword?

Compiling with VS2012 and working with the DirectXMath library, I encountered an issue where it appeared that the compiler wasn't aligning my XMMATRIX. I simplified the issue down to the following.

#include <DirectXMath.h>
using namespace DirectX;

int _tmain(int argc, _TCHAR* argv[])
{
  auto m1 = XMMatrixIdentity();
  auto m2 = XMMatrixIdentity();

  auto t1 = XMMatrixTranspose( m1 ); // sometimes access violation occurs here
  auto t2 = XMMatrixTranspose( m2 ); // or sometimes here

  return 0;
}

Re-running the code over and over will sometimes cause an "Access violation reading location 0xFFFFFFFF" on the first transpose, sometimes on the second.

I've figured out this is due to the fact that m1 and m2 are not being properly aligned. Replacing "auto" with "XMMATRIX" seems to solve the issue, so my suspicion is a compiler bug, but its also possible that I'm doing something wrong, or not enabling some option.

Is there something wrong with my code or is this a compiler bug?

like image 781
MerickOWA Avatar asked Sep 04 '12 00:09

MerickOWA


People also ask

What is alignas in c++?

The alignas type specifier is a portable, C++ standard way to specify custom alignment of variables and user defined types. The alignof operator is likewise a standard, portable way to obtain the alignment of a specified type or variable.

What is the alignment of malloc?

new and malloc, by default, align address to 8 bytes (x86) or 16 bytes (x64), which is the optimal for most complex data.

Why does the compiler sometimes insert padding between fields and or at the end of a struct?

structure A If the short int element is immediately allocated after the char element, it will start at an odd address boundary. The compiler will insert a padding byte after the char to ensure short int will have an address multiple of 2 (i.e. 2 byte aligned).


1 Answers

The definition for XMMATRIX has the following in the header file (xnamath.h), although this could be different in your version.

// Matrix type: Sixteen 32 bit floating point components aligned on a
// 16 byte boundary and mapped to four hardware vector registers
#if (defined(_XM_X86_) || defined(_XM_X64_)) && defined(_XM_NO_INTRINSICS_)
typedef struct _XMMATRIX
#else
typedef _DECLSPEC_ALIGN_16_ struct _XMMATRIX
#endif

So XMMATRIX is defined with __declspec(align(16)) (if you look through the header files it does reduce to this), which is a Microsoft specific extension. It's not a macro. This means it's a compiler bug, the compiler is failing to propagate these proprietary attributes to variables defined with the auto keyword.

It's probably best to just avoid the use of the auto keyword in this case, it's probably neater than explicitly adding the declspec yourself.

like image 162
jleahy Avatar answered Oct 20 '22 17:10

jleahy