【发布时间】:2018-05-24 14:12:39
【问题描述】:
以下代码将两个 4 维单位矩阵相乘:
const Matrix4 id = Matrix4(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
auto & a = id;
auto & b = id;
auto m1 = Matrix4(
a.data[0] * b.data[0] + a.data[4] * b.data[1] + a.data[8] * b.data[2] +
a.data[12] * b.data[3],
a.data[0] * b.data[4] + a.data[4] * b.data[5] + a.data[8] * b.data[6] +
a.data[12] * b.data[7],
a.data[0] * b.data[8] + a.data[4] * b.data[9] + a.data[8] * b.data[10] +
a.data[12] * b.data[11],
a.data[0] * b.data[12] + a.data[4] * b.data[13] + a.data[8] * b.data[14] +
a.data[12] * b.data[15],
a.data[1] * b.data[0] + a.data[5] * b.data[1] + a.data[9] * b.data[2] +
a.data[13] * b.data[3],
a.data[1] * b.data[4] + a.data[5] * b.data[5] + a.data[9] * b.data[6] +
a.data[13] * b.data[7],
a.data[1] * b.data[8] + a.data[5] * b.data[9] + a.data[9] * b.data[10] +
a.data[13] * b.data[11],
a.data[1] * b.data[12] + a.data[5] * b.data[13] + a.data[9] * b.data[14] +
a.data[13] * b.data[15],
a.data[2] * b.data[0] + a.data[6] * b.data[1] + a.data[10] * b.data[2] +
a.data[14] * b.data[3],
a.data[2] * b.data[4] + a.data[6] * b.data[5] + a.data[10] * b.data[6] +
a.data[14] * b.data[7],
a.data[2] * b.data[8] + a.data[6] * b.data[9] + a.data[10] * b.data[10] +
a.data[14] * b.data[11],
a.data[2] * b.data[12] + a.data[6] * b.data[13] + a.data[10] * b.data[14] +
a.data[14] * b.data[15],
a.data[3] * b.data[0] + a.data[7] * b.data[1] + a.data[11] * b.data[2] +
a.data[15] * b.data[3],
a.data[3] * b.data[4] + a.data[7] * b.data[5] + a.data[11] * b.data[6] +
a.data[15] * b.data[7],
a.data[3] * b.data[8] + a.data[7] * b.data[9] + a.data[11] * b.data[10] +
a.data[15] * b.data[11],
a.data[3] * b.data[12] + a.data[7] * b.data[13] + a.data[11] * b.data[14] +
a.data[15] * b.data[15]);
const int diff_index = 15;
std::cout << "Actual value of element " << diff_index << " is " << m1.data[diff_index] << " expected " << id.data[diff_index] << std::endl;
很明显,生产的第 15 个元素是 1.0f,在发布配置中是 1.0f,但在 我的项目的调试配置中,我得到 0.0f。
我试图通过使用我的项目中的编译器选项在命令行编译单个 .cpp 文件来重现这一点:
cl /GS /TP /W3 /Zc:wchar_t /Zi /Gm- /Od /Ob0 /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /RTC1 /GR /Gd /MDd /FC /EHsc /nologo /diagnostics:classic MatrixTest.cpp
但这会输出 1.0f。只有当我将 MatrixTest.cpp 编译为我的项目的一部分时,我才能获得 0.0f。
下面我提供了绝对微不足道的Matrix类的定义:
struct Matrix4
{
float data[16];
Matrix4(float m00,
float m01,
float m02,
float m03,
float m10,
float m11,
float m12,
float m13,
float m20,
float m21,
float m22,
float m23,
float m30,
float m31,
float m32,
float m33)
{
data[0] = m00;
data[4] = m01;
data[8] = m02;
data[12] = m03;
data[1] = m10;
data[5] = m11;
data[9] = m12;
data[13] = m13;
data[2] = m20;
data[6] = m21;
data[10] = m22;
data[14] = m23;
data[3] = m30;
data[7] = m31;
data[11] = m32;
data[15] = m33;
}
};
我相信,这不是内存损坏的结果,因为我的项目绝对是微不足道的,而且这段代码已经在某些实际应用中运行了很长时间,所以我认为肯定发生了一些奇怪的事情。
更新 1:
VS2017 15.7.1,编译器版本为:Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
项目的配置是Debug 64bit。
编译器选项(省略 /I 和 /D)为: /GS /TP /W3 /Zc:wchar_t /Zi /Gm- /Od /Ob0 /Fd"ModelTest.dir\Debug\vc141.pdb" / Zc:inline /fp:precise /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "CMAKE_INTDIR=\"Debug\"" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope / RTC1 /GR /Gd /MDd /FC /Fa"Debug/" /EHsc /nologo /Fo"ModelTest.dir\Debug\" /Fp"ModelTest.dir\Debug\ModelTest.pch" /diagnostics:classic
项目(.sln 和 .vcxproj)由 cmake-3.11.2-win64-x64 生成。
【问题讨论】:
-
如果您提供的代码不能产生问题,那么问题一定出在您没有提供的代码上。似乎您在其他地方有未定义的行为,并且所有这些代码都与识别实际问题无关。
-
我的 VS2017 编译器版本是 Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
-
仍然......这只是基本的数学。没有什么特别的,甚至资格 矩阵乘法 都很强。优化器可以做一些技巧,但如果你正在调试,那是不可能的。也许你的 cpp 文件中还有其他东西导致了这种行为。顺便说一句,在发布版本中没有它你是如何编译的?
-
在我的项目中,我只是从 main() 调用 testMatrix() 并返回。
标签: c++ visual-studio