微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GCC 优化忽略循环条件

如何解决GCC 优化忽略循环条件

所以我写了这段代码

#include <iostream>

constexpr
int fibonacci (int n) {
    int a = 0;
    int b = 1;

    for(auto i = 0; i < n; i++) {
        b += a;
        a = b - a;
    }
    return b;
}

template<int N,int (T)(int)>
struct array {
    using type = decltype(T(0));

    constexpr array() : arr() {
        for (auto i = 0; i < N; ++i) {
            arr[i] = T(i);
        }
    }
    const type &operator[](int i) const { return arr[i]; }

private:
    type arr[N];
};

int main() {
    constexpr auto x = array<10,fibonacci>();

    for (int i = 0; i < 11; i++) {
        std::cout << i << " " << x[i] << std::endl;
    }
}

如果没有优化,它会按预期工作,打印 11 个值,最后一个随机值。但是一旦我移动到 -O2,我就会随机得到一长串以崩溃和分段错误完成的数字。 我在godbolt.org (https://godbolt.org/z/4MqjbPbxE) 上查看了这个结果,似乎在例如clang 中没有问题。

我的问题是,这是 gcc 中的错误吗?为什么优化会删除/不检查 for 循环中的条件?

解决方法

您正在使用超出范围的 x[i] 调用未定义的行为

再分配一个以避免超出范围的访问。

换句话说,

    constexpr auto x = array<10,fibonacci>();

应该

    constexpr auto x = array<11,fibonacci>();

定义常量以避免拼写错误更好:

int main() {
    constexpr int num = 11;
    constexpr auto x = array<num,fibonacci>();

    for (int i = 0; i < num; i++) {
        std::cout << i << " " << x[i] << std::endl;
    }
}
,

修复检查索引。

for (int i = 0; i ; i++) {

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。