14

使用 VS2012 编译并使用 DirectXMath 库时,我遇到了一个问题,编译器似乎没有对齐我的 XMMATRIX。我将问题简化为以下内容。

#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;
}

一遍又一遍地重新运行代码有时会在第一次转置时导致“访问冲突读取位置 0xFFFFFFFF”,有时在第二次。

我发现这是因为 m1 和 m2 没有正确对齐。用“XMMATRIX”替换“auto”似乎可以解决问题,所以我怀疑是编译器错误,但也有可能我做错了什么,或者没有启用某些选项。

我的代码有问题还是编译器错误?

4

3 回答 3

3

的定义XMMATRIX在头文件 ( xnamath.h) 中有以下内容,尽管这在您的版本中可能有所不同。

// 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

所以XMMATRIX定义为__declspec(align(16))(如果你查看头文件,它确实会简化为这个),它是 Microsoft 特定的扩展。这不是宏。这意味着它是一个编译器错误,编译器无法将这些专有属性传播到使用auto关键字定义的变量。

在这种情况下最好避免使用关键字,它可能比显式添加自己auto更整洁。declspec

于 2012-09-07T16:07:15.157 回答
2

这绝对是一个编译器错误。我也可以用我自己的数学课重现它。我在这里开了一张票,所以投票给它。如前所述,您可以避免使用 auto 关键字。或者您可以编译到不存在错误的 x64(或者至少我无法重现它;我的不那么简单的程序可以完美运行)。

于 2012-12-27T20:22:41.670 回答
0

对于 Visual Studio 2012,我能够通过将语句分成两行来实现“解决方法”:

XMMATRIX mtxMyWorldTrnspd = mtxMyWorld;
mtxMyWorldTrnspd = XMMatrixTranspose(mtxMyWorldTrnspd);
于 2014-06-11T06:11:00.790 回答