警告C26451:算术溢出
Warning C26451: Arithmetic overflow
如何解决这些警告?
// midiNote is a double as it is used in floating point equation
// v is int because that's informative that the function wants whole numbers
void setMidiNote(int v) { midiNote = v-48; }
警告C26451算术溢出:在4个字节值上使用操作员' - ',然后将结果施放为8个字节值。在调用操作员" - "之前将值施放给更宽的类型,以避免溢出(io.2(。
// input should be 0 to 10 integer, and dank will be odd integers only
// dank is a double, it is ultimately used in a floating point equation
void setDarkIntensity(int v) { dank = v * 2 + 1; }
警告C26451算术溢出:在4个字节值上使用操作员'*',然后将结果施放为8个字节值。在调用操作员"*"以避免溢出之前,将值施放为更宽的类型(io.2(。
警告C26451算术溢出:在4个字节值上使用操作员' ',然后将结果施放为8个字节值。在调用操作员为" "之前,将值施放为更宽的类型,以避免溢出(io.2(。
我相信这是VS2019中的错误。它不再在VS2022中标记。
例如,这会产生警告
double test2(int n)
{
return 4.0 * (n - 1);
}
但这不是
int test2a(int n)
{
return 4 * (n - 1);
}
然而,后者的不确定行为的风险要大得多。乘以4大大增加了UB的风险,因为大量的N会产生UB。多么伟大?好吧,在大约40亿可能的值中,n
只有一个可能的值在溢出的第一个示例中。在第二个中,大约有30亿n
S可以超越/下水。为什么?因为整数算术是不可能的。
可以说,要警告,要警告几乎可以警告INT上的任何算术操作。
此答案显示了一种在vs 2019中禁用此警告的方法。
警告C26454:算术溢出:' - '操作在编译时间(io.5(
时产生负面的无符号结果但是,从VS2022开始,Microsoft不再为此产生C26451警告。它也不显示在-wall下。他们显然看到了光。
警告告诉您,您的计算有可能在转换为结果(较大(类型之前溢出原始(较小(类型。在第一种情况下,如果v
是min_int(-2 31 (,则减去收集将下流,从而导致不确定的行为(可能是大的正数(,然后将其存储在midiNote
中。为避免警告,请先转换为较大的类型:
midiNote = double(v) - 48;
对于您的第二个示例类似。
虽然您知道setMidiNote
不会带有这个问题的值,但 compiler 不知道并发出警告,以提醒您可能出现问题的可能性。
我通过查看一些Microsoft文档解决了问题,但是您也可以将变量更改为long long
类型(我知道在顶部(。它摆脱了我的错误。希望他们很快解决这个问题。
我通过将变量的类型更改为"未签名的__int64"来摆脱警告。这就是微软的开发人员社区建议!
要解决您的问题,将参数V铸造为64位类型:
void setMidiNote(int v) { midiNote = static_cast<int64_t>(v) - 48; }
void setDarkIntensity(int v) { dank = static_cast<int64_t>(v) * 2 + 1; }
在VS 2019上测试16.9.6
来源:https://develovercommunity.visualstudio.com/t/invalid-error-c26451/279594#t-n404080https://learn.microsoft.com/en-us/cpp/code-quality/c26451
static_cast&lt;&gt;((是推荐的解决方案。.目前我正在阅读的书对此新铸造惯例进行了很大的收益。作为C风格..(根据文献(..我想知道..是否将其宣布为自动。听起来矢量可以做到……
void setDarkStrentty(auto v({dank = v * 2 1;}
施放到您想要的数据类型上,然后一直使用:
// midiNote is a double as it is used in floating point equation
// v is int because that's informative that the function wants whole numbers
void setMidiNote(int v) { midiNote = static_cast<double>(v) - 48.0; }
// input should be 0 to 10 integer, and dank will be odd integers only
// dank is a double, it is ultimately used in a floating point equation
void setDarkIntensity(int v) { dank = static_cast<double>(v) * 2.0 + 1.0; }
曾经是整数操作比浮点快得多,但是在现代CPU上不再是正确的。
使用2.0
代替2
迫使v
的铸件隐式地施放到double
,但显式始终更清楚。
奖励建议:考虑验证调试构建中的任何假设。将来更改代码时,这将有助于避免破坏这些假设。类似:
// input should be 0 to 10 integer, and dank will be odd integers only
// dank is a double, it is ultimately used in a floating point equation
void setDarkIntensity(int v)
{
assert(v >= 0 && v <= 10);
dank = static_cast<double>(v) * 2.0 + 1.0;
}
奖励建议2:如果这些功能不是类的一部分,我会标记它们inline
,因此优化器有更好的机会使用这些简单的功能来完成其操作。如果它们是班级定义的一部分,那么这是隐式完成的。
- 'short int'持有的值溢出,但"自动"不会溢出?
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 大于65535的C++数组[size]引发不一致的溢出
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- C++中无符号字符溢出
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 整数溢出,最大值为 pow(10,19)
- 获取隐式转换溢出从无符号到已签名的警告
- 使用 strcat 获取缓冲区溢出错误
- LeetCode 1:两和 - 地址清理器:堆缓冲区溢出地址
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- C++ 对象数组堆栈溢出
- 使用提升::lexical_cast捕获溢出
- C++ Unordered_set功能中的溢出
- 自定义排序函数中的堆溢出
- 使用向量的缓冲区溢出
- 有没有一种方法可以捕获进程中的堆栈溢出?C++Linux
- 如何修复此特征矩阵反演溢出错误?
- 警告C26451:算术溢出