为什么 g++-11 '-O2' 包含错误而 '-O0' 正常?
Why does g++-11 '-O2' contain a bug while '-O0' is ok?
#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
没问题?
当a
和b
的类型是int
和a
是INT_MIN
和[=12时,b - a + 1
显然是UB =] 是 INT_MAX
因为有符号溢出是未定义的行为。
When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined
在执行计算之前,您不会转换为 int64_t
。
#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
没问题?
a
和b
的类型是int
和a
是INT_MIN
和[=12时,b - a + 1
显然是UB =] 是 INT_MAX
因为有符号溢出是未定义的行为。
When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined
在执行计算之前,您不会转换为 int64_t
。