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

xml*_*lmx -1 c++ gcc g++ internal-compiler-error c++20

#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;
}
Run Code Online (Sandbox Code Playgroud)

g++-11 -std=c++20 -O2应该输出0比其他1

clang++ 没问题。如果我-O2改为-O0,g++-11 也可以。

参见:在线演示

为什么 g++ -O2 包含一个错误而 -O0 可以?

Mes*_*kon 5

b - a + 1aand bareintaisINT_MINbis的类型为有INT_MAX符号溢出时,显然是 UB是未定义的行为。

来自cppreference:

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

int64_t直到计算完成后,您才转换为。

  • 尽管 c++20 强制执行 2 的补码有符号整数,但它并没有说明有关此上下文中的溢出的任何新内容 (3认同)
  • @NathanOliver 该规则是关于整数转换的。它不适用于算术溢出。 (3认同)