首页 > 解决方案 > 为什么 glm::mat3 和 glm::value_ptr 创造了一个穿越时间和宇宙的黑洞,并且正在破坏我脑海中任何可能的逻辑?

问题描述

我正在使用非常著名的 OpenGL 框架创建一个漂亮的图形引擎,但后来我遇到了一个意想不到的问题(就像每个问题一样)。

我必须创建一个函数来修改 glm::mat3 中的特定值。为此,我创建了一个简单的函数,该函数返回一个对 glm::mat3 中特定浮点数的简单引用,但似乎没有任何效果,因为我不知道是什么原因。

这是我的功能:

float& mat3ValueAt(glm::mat3& m, int l, int c) {
    // l is the line index and c is the column index...
    return glm::value_ptr(m)[3 * l + c];
}

要查看它是否有效,我必须使用一个能够显示我的矩阵的函数:

std::ostream& operator<<(std::ostream& stream, glm::mat3 m) {
    for (int i = 0; i < 9; i++) {
        stream << GLS::mat3ValueAt(m, i / 3, i % 3) << ((i + 1) % 3 ? ' ' : '\n');
    }
    return stream;
}

所有这些都不起作用......但没关系......这一定是我的错......所以我将我看起来不错的不起作用的代码减少到我可以找到异常的最小代码......

这就是我最终完全生气的事情,这让我发疯了:

int main() {
    glm::mat3 m;
    std::cout << "display uninitialised value..." << std::endl;
    std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display an uninitialised value
    *(glm::value_ptr(m) + 5) = 42;
    std::cout << "display the initialised value" << std::endl;
    std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display 42
}

这个小代码的结果是......

display uninitialised value...
42
display the initialised value
42

所以我之前的两个函数不起作用的事实是好的,也许我只是不知道 value_ptr 是如何工作的......但我很确定一件事......一个值不能有我们的价值'将在分配给它之前分配它!

我放的值而不是 42 并不重要,它总是在我分配之前分配!

这怎么可能?

标签: c++glm-math

解决方案


这:

glm::mat3 m;

创建一个未初始化的对象;此对象的内容具有不确定的值。任何读取具有不确定值的对象的值的尝试都会导致未定义的行为。

因此,编译器可以自由地重新排序您的代码,使其如下所示:

int main() {
    glm::mat3 m;
    *(glm::value_ptr(m) + 5) = 42;
    std::cout << "display uninitialised value..." << std::endl;
    std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display an uninitialised value
    std::cout << "display the initialised value" << std::endl;
    std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display 42
}

This is perfectly valid because if you tried to read from the value before initializing it, you're in undefined behavior land, and having that value already be initialized is no more correct than any other undefined behavior.


推荐阅读