Search code examples
c++visual-studiomfcvisual-studio-2019

C26451 Arithmetic overflow accessing items in a CStringArray


Got this code:

CString CMeetingScheduleAssistantApp::UpdateDateFormatString(COleDateTime& rDate, CString strDateFormatString)
{
    CString     strDayNumber, strNewDateFormatString = strDateFormatString;

    if (theApp.UseTranslationINI())
    {
        strNewDateFormatString.Replace(_T("%B"),
            m_aryDateTrans[DATE_TRANS_MONTH][rDate.GetMonth() - 1]);
        strNewDateFormatString.Replace(_T("%A"),
            m_aryDateTrans[DATE_TRANS_DAY][rDate.GetDayOfWeek() - 1]);
        strNewDateFormatString.Replace(_T("%b"),
            m_aryDateTrans[DATE_TRANS_MONTH_SHORT][rDate.GetMonth() - 1]);
        strNewDateFormatString.Replace(_T("%a"),
            m_aryDateTrans[DATE_TRANS_DAY_SHORT][rDate.GetDayOfWeek() - 1]);

        strDayNumber = rDate.Format(_T("%d"));
        strNewDateFormatString.Replace(_T("%d"), strDayNumber);
        strDayNumber = rDate.Format(_T("%#d"));
        strNewDateFormatString.Replace(_T("%#d"), strDayNumber);
    }

    return strNewDateFormatString;
}

For the four Replace lines of code I am getting code analysis warning:

Warning C26451

Arithmetic overflow: Using operator '-' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '-' to avoid overflow (io.2).

The first value inside the [ and ] brackets is of type int, but the second is a literal value of 1:

Code

The variable m_aryDateTrans is defined as:

CStringArray m_aryDateTrans[NUM_DATE_TRANS];

So I am not sure what casting I need to make here to suppress this warning.

I am compiling in 32 bit and 64 bit environments.


Solution

  • The [] operator of CStringArray takes an INT_PTR argument, which is 64-bits in x64 builds and 32-bits for x86. So, you should use the (rather clumsy-looking) code shown below:

    strNewDateFormatString.Replace(_T("%B"),
                m_aryDateTrans[DATE_TRANS_MONTH][INT_PTR(rDate.GetMonth()) - INT_PTR(1)]);
    

    (You may be able to get away without the 2nd cast - try it and see!)