Выравнивание 16 не соблюдается при использовании ключевого слова auto?
Компиляция с 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", похоже, решает проблему, поэтому мое подозрение является ошибкой компилятора, но также возможно, что я делаю что-то неправильно или не позволяю некоторые опции.
Что-то не так с моим кодом или это ошибка компилятора?
Ответы
Ответ 1
Определение для 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
самостоятельно.
Ответ 2
Это определенно ошибка компилятора. Я могу воспроизвести его тоже своими собственными математическими классами.
Я открыл билет здесь, чтобы проголосовать за него.
Вы можете избежать использования ключевого слова auto, как было упомянуто. Или вы можете скомпилировать x64, где ошибка отсутствует (или, по крайней мере, я не смог ее воспроизвести, моя не очень простая программа работает отлично).
Ответ 3
Для Visual Studio 2012 я смог реализовать "обход", разделив оператор на две строки:
XMMATRIX mtxMyWorldTrnspd = mtxMyWorld;
mtxMyWorldTrnspd = XMMatrixTranspose(mtxMyWorldTrnspd);