我正在尝试验证嵌套循环中的矩阵值以进行单元测试。测试通过了macOS(clang),但未通过Ubuntu 18.04(gcc版本7.3.0)。
这是我要尝试做的(我要验证结果(m3
是身份矩阵):
mat3 m1 = GLM_MAT3_IDENTITY_INIT;
mat3 m2 = GLM_MAT3_IDENTITY_INIT;
mat3 m3;
int i, j, k;
/* test identity matrix multiplication */
glm_mat3_mul(m1, m2, m3);
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (i == j) {
assert_true(glm_eq(m3[i][j], 1.0f));
} else {
assert_true(glm_eq(m3[i][j], 0.0f));
}
}
}
这在Ubuntu / gcc上失败,但在macOS上通过。如果我在 i 变量上使用 volatile ,那么它也会在Ubuntu上传递:
mat3 m1 = GLM_MAT3_IDENTITY_INIT;
mat3 m2 = GLM_MAT3_IDENTITY_INIT;
mat3 m3;
volatile i;
int j, k;
/* test identity matrix multiplication */
glm_mat3_mul(m1, m2, m3);
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (i == j) {
assert_true(glm_eq(m3[i][j], 1.0f));
} else {
assert_true(glm_eq(m3[i][j], 0.0f));
}
}
}
如果我在if (i == j) {
语句之前打印i和j值而没有使用volatile,那么它也会通过。可能会缓存 i ,而在下一次迭代时不会加载新的 i 值。但这对于 mat4 测试也是如此,对于 mat4
使用一个条件(真条件或假条件)会导致测试通过,但如果将if与else一起使用会导致测试失败。
我正在使用cmocka进行测试,并运行make check
命令来运行测试。
mat3 和 mat4 定义:
typedef float vec2[2];
typedef CGLM_ALIGN_IF(8) float vec3[3];
typedef int ivec3[3];
typedef CGLM_ALIGN_IF(16) float vec4[4];
#ifdef __AVX__
typedef CGLM_ALIGN_IF(32) vec3 mat3[3];
typedef CGLM_ALIGN_IF(32) vec4 mat4[4];
#else
typedef vec3 mat3[3];
typedef CGLM_ALIGN_IF(16) vec4 mat4[4];
#endif
我应该在这里使用 volatile 吗?还是我的测试代码有什么问题?
PS:对Ubuntu上的 mat4 通过相同的测试,但对于 mat3
则失败编辑:
使用glm_eq(a, b)
比较浮点值:
CGLM_INLINE
bool
glm_eq(float a, float b) {
return fabsf(a - b) <= FLT_EPSILON;
}