首页 > 解决方案 > 使用两个整数时 Visual Studio 生成溢出警告

问题描述

我在 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 字节值。在调用运算符'-'之前将值转换为更广泛的类型以避免溢出

当我所做的只是一个简单的整数减法时,为什么会出现警告?

评论后补充:

整个函数太长太复杂,无法在此处发布。该函数的主要工作是将 a 中的数据点转换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.

标签: c++visual-studioqtc++17overflow

解决方案


我通过使用解决了它const_iteratorstd::prev并且std::next

std::vector<int> cx;
// code to fill cx

// Iterators for cx
std::vector<int>::const_iterator ix0;
std::vector<int>::const_iterator ix1;

ix1 = cx.cbegin();

for(ix0 = cx.cbegin(); ix0 != std::prev(cx.cend()); ++ix0){
    ix1 = std::next(ix1);
    if (*ix1 < 0)
        continue;
    else if (*ix0 >= pData.size())
        break;
    else {
        if (*ix0 < 0)
            iStrt = pData.cbegin();
        else
            iStrt = std::next(pData.cbegin(), *ix0);

        if (*ix1 >= pData.size())
            iStop = pData.cend();
        else
            iStop = std::next(pData.cbegin(), *ix1);
    }
}

我还没有尝试过整个功能。如果这不起作用,我会更新。


推荐阅读