Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do usual arithmetic conversions work?

I was running this code in VS2019:

#include<iostream>
#include<string>
#include<typeinfo>
using namespace std;

int main() {
    string mystring = "hello world";
    for (int j = 0; j < 10; j++) {
        if (mystring[j + 1] == 'w') {
            cout<<"string contains w letter\n";
        }
        else {
            continue;
        }
        return 0;
    }
}

And I realized that when I run it on Debug mode on an x86 platform, everything is ok, but if I change the platform to x64, the following warning appears:

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

It seems to be related to Usual arithmetic conversions, such that, if the operands are of different types, a conversion is applied to one of them before calculation. But if they are equal, that still happens?

If I print typeid(j).name() and typeid(1).name(), it prints int for both, so what is the reason for this warning? The warning is fixed if I change the if condition to (mystring[j + static_cast<__int64>(1)] == 'w'). The explanation, I think, should be that the number '1' is not considered of type int on x64, or it is but occupies different bits of memory than the int type on x64.

I would really like to clarify the issue, thanks.

like image 296
Spherk Avatar asked Feb 05 '26 12:02

Spherk


1 Answers

The "C26451" warning is not a standard compiler warning. It's part of the C++ Code Guidelines Checker which is giving you 'recommendations'. For more on this feature, see Microsoft Docs.

In C++ Core Guidelines the specific recommendation the checker is using here is: ES.103: Don't overflow.

The reason this only happens in x64 is because size_t is 64-bits while int is 32-bits. In x86, both int and size_t are 32-bits.

The std::string operator[] takes a size_t. The cleanest simplest fix here is:

for (size_t j= 0; j <10; j++)

You could also address this by explicitly promoting the int to size_t before the addition takes place:

if (mystring[size_t(j) + 1] == 'w') {

You could also ignore the warning by adding:

#pragma warning(disable : 26451)

Or you could disable the C++ Core Guidelines Checker.

like image 96
Chuck Walbourn Avatar answered Feb 07 '26 09:02

Chuck Walbourn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!