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

为什么 g++-11 '-O2' 包含错误而 '-O0' 没问题?

如何解决为什么 g++-11 '-O2' 包含错误而 '-O0' 没问题?

#include <limits>
#include <cstdint>
#include <iostream>

template<typename T>
T f(T const a = std::numeric_limits<T>::min(),T const b = std::numeric_limits<T>::max())
{
    if (a >= b)
    {
        throw 1;
    }

    auto n = static_cast<std::uint64_t>(b - a + 1);
    if (0 == n)
    {
        n = 1;
    }

    return n;
}

int main()
{
    std::cout << f<int>() << std::endl;
}

g++-11 -std=c++20 -O2 应该输出 0 而非 1

clang++ 正常。如果我把-O2改成-O0,g++-11也可以。

见:online demo

为什么 g++ -O2 包含错误 -O0 没问题?

解决方法

b - a + 1a 的类型为 bintaINT_MIN 时,

b 显然是 UB是 INT_MAX,因为有符号溢出是未定义的行为。

来自cppreference:

当有符号整数算术运算溢出(结果不适合结果类型)时,行为未定义

在计算完成之前,您不会转换为 int64_t

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