gpt4 book ai didi

gcc - GCC中不同优化级别的不同输出

转载 作者:行者123 更新时间:2023-12-03 14:32:21 24 4
gpt4 key购买 nike

我正在重写我上学期为大学开发的光线追踪器,但遇到了以下问题:
当我在 Debug 中编译和运行我的代码时,输​​出符合预期

expected result

但是当我启用更高的优化级别时,例如“-O2”结果完全不同:

actual result

我不确定为什么会发生这种情况。我追踪到球体相交代码

//#pragma GCC push_options
//#pragma GCC optimize("O0")

Intersection Sphere::intersect(const Ray& ray, const float previous) const
{
const auto oc = ray.origin - center_;
const auto lhv = -dot(ray.direction, oc);
const auto discriminant = lhv * lhv - (oc.lensqr() - radius_ * radius_);

if (discriminant < 0.0F)
{
return Intersection::failure();
}
float distance;
const auto rhv = std::sqrt(discriminant);
const auto r = std::minmax(lhv + rhv, lhv - rhv);
if (r.first <= 0.0F)
{
if (r.second <= 0.0F)
{
return Intersection::failure();
}
distance = r.second;
}
else
{
distance = r.first;
}

const auto hit = ray.getPoint(distance);
const auto normal = (hit - center_).normalize();

if (0.0F <= distance && distance < previous - epsilon)
{
return {distance, ray, this, normal, hit};
}
return Intersection::failure();
}

//#pragma GCC pop_options

如果我在 Release模式下取消注释 pragma,我会再次得到预期的结果。也许我的代码中有一些未定义的行为会导致这种情况?

您也可以在此处查看,因为不容易实现最小的可重现示例。 https://github.com/Yamahari/RayTracer/blob/master/rt/solid/Sphere.cpp

(您也可以克隆 repo 并使用 cmake 构建项目,您只需要 SFML 作为依赖项。

将 -DSFML_INCLUDE_DIR="include_dir"和 -DSFML_LIB_DIR="lib_dir"与使用所需编译器编译的 sfml 库一起使用)

最佳答案

std::minmax返回对其参数的一对引用。如果使用纯右值作为参数调用它,则该对中的引用将在完整表达式结束后悬空,这意味着访问 r.first

if (r.first <= 0.0F)

这里会有未定义的行为。

所以存储 lhv + rhvlhv - rhv在变量中并调用 std::minmax在他们身上或使用
std::minmax({lhv + rhv, lhv - rhv})

选择 std::initializer_list重载,它返回一对实际值。

正如@Jarod42 在评论中所指出的,您实际上并不需要 std::minmax这里。 rhvstd::sqrt 的结果调用,所以它总是非负的,使得 lhv + rhv总是更大(或相等)的值。

关于gcc - GCC中不同优化级别的不同输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60849247/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com