【发布时间】:2021-02-09 16:13:17
【问题描述】:
我在 Visual Studio Community 2019 工作,并且在向量的 [] 运算符中使用减号时收到 C26451:算术溢出警告。我的代码:
std::vector<int> cx;
// code to fill cx
// iStrt and iCnst are constant iterators and pData is my data vector
for (int ii = 1; ii < cx.size(); ++ii) {
if (cx[ii - 1] < 0) // C26451: Arithmetic Overflow
iStrt = pData.cbegin();
else
iStrt = iCnst + cx[ii - 1]; // C26451: Arithmetic Overflow
}
整个警告是:
C26451:算术溢出:对 4 字节值使用运算符“-”,然后将结果转换为 8 字节值。在调用运算符'-'之前将值转换为更广泛的类型以避免溢出
当我所做的只是一个简单的整数减法时,为什么会出现警告?
在 cmets 之后添加:
整个函数太长太复杂,这里就不贴了。该函数的主要工作是将std::vector<double> pData 中的数据点转换为屏幕坐标。
我在上面发布的内容与下面的内容或多或少相同。下面的代码有更多的解释。这是我功能的基本部分,我认为它应该是可重现的。
void UPlot::plotData()
{
// This vector contains indexes for data plotting
// i.e. pData[cx[1]] - pData[cx[0]] will be plotted
// in a single column of pixels
std::vector<int> cx;
// constant values:
// w_ = width in pixels (e.g. 500)
// lft_ = Start data index (e.g. 150)
// rit_ = End data index (e.g. 10000)
// xFact_ = (rit_ - lft_) / w_ i.e. translation factor
for(int ii = 0; ii < (w_ + 1); ++ii)
cx.push_back(round(lft_ + (ii * xFact_)));
// since the difference between cx[ii] - cx[ii-1] is
// required, cx has to be greater than 1
if (cx.size() > 1) {
iCnst = pData.cbegin();
// iterate over cx and find out the number of data points
// that will be plotted in a single column of pixels
for (int ii = 1; ii < cx.size(); ++ii) {
if (cx[ii] < 0)
continue; // only +ve indexes can work
else if (cx[ii - 1] >= pData.size())
break; // reached end of pData
else {
// The condition in which pData values will be
// translated into pixel values
// find the starting iterator
if (cx[ii - 1] < 0)
iStrt = pData.cbegin();
else
iStrt = iCnst + cx[ii - 1];
// Find the end iterator
if (cx[ii] >= pData.size())
iStop = pData.cend();
else
iStop = iCnst + cx[ii];
/* ----- Rest of the code ----- */
}
}
}
}
还要注意,在此之前,我使用的是 QVector 而不是 std::vector,而且我从未收到过 QVector 的警告。
【问题讨论】:
-
警告并不意味着您的代码错误。它只是意味着在某些情况下它可能是错误的,并且该消息解释了原因。如果它不适用于您的情况,您有两个选择:修复代码以使警告静音或忽略警告
-
除非你想使用负索引(这是可能的,但很少使用)我的建议是始终使用
unsigned类型作为数组索引。 -
@Someprogrammerdude 如果循环从
0开始,则停止条件变为ii < cx.size() - 1,这将触发下一个警告;) -
谁,多么糟糕的错误信息。 “转换结果”是错误的——代码中没有转换。 4 字节与 8 字节不是问题。问题在于将有符号值转换为无符号值 - 转换负值可能会导致意外。
-
@idclev463035818 你能分享在这种情况下如何最好地做到这一点吗?我自己在使用向量大小时有时会遇到类似的问题,所以我个人会对在这种情况下设置循环的“最佳”或标准方式感兴趣,这样它既可以相对避免错误,又可以编译器即使在严格的设置下也很开心。
标签: c++ visual-studio qt c++17 overflow