c++ - 为什么 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 也可以。
参见:在线演示
为什么 g++在正常的情况下 -O2
包含错误 -O0
?
解决方案
b - a + 1
a
当and b
are的类型int
和a
is INT_MIN
and b
is INT_MAX
as 有符号溢出是未定义的行为时,显然是 UB 。
当有符号整数算术运算溢出(结果不适合结果类型)时,行为未定义
int64_t
在计算已经执行之前,您不会转换为。
推荐阅读
- http - 如何在 Go 中的测试中模拟 http 请求的 504 超时错误?
- reactjs - 从 JSON 对象 data.results 设置状态时反应 16 出错
- javascript - 如何在 Node.js 的 Selenium 脚本中访问控制台中的变量?
- javascript - How to push object by following its structure to array of objects
- asp.net-web-api - Swagger 在路由调整后显示相同方法的两个端点
- sql-server - 为 TFS 安装 SQL 分析服务的原因是什么?
- java - HTML 选项卡不会重定向到上一个选定的选项卡,而是重定向到第一个选项卡
- android - 浮动操作按钮 + 协调器 Layot + 位置和放置问题
- encryption - 如何区分实时流量中的加密和压缩
- reactjs - 使用 MathML 标签反应 16 个 HTML 属性