通常的算术转换如何工作?

我在 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 lettern";
        }
        else {
            continue;
        }
        return 0;
    }
}

我意识到当我在 x86 平台上以 Debug 模式运行它时,一切正常,但是如果我将平台更改为 x64,则会出现以下警告:

C26451 算术溢出:对 4 字节值使用运算符“+”,然后将结果转换为 8 字节值。在调用运算符“+”之前将值转换为更宽的类型以避免溢出(io.2)。

它似乎与常用算术转换有关,因此,如果操作数是不同类型,则在计算之前将转换应用于其中之一。但如果它们相等,那还会发生吗?

如果我打印typeid(j).name()and typeid(1).name(),它会同时打印int两个,那么这个警告的原因是什么?如果我将if条件更改为 ,则警告已修复(mystring[j + static_cast<__int64>(1)] == 'w')。我认为,解释应该是数字“1”不被视为intx64 上的类型,或者它占用的内存位与intx64 上的类型不同。

我真的很想澄清这个问题,谢谢。

回答

“C26451”警告不是标准的编译器警告。它是 C++ 代码指南检查器的一部分,它为您提供“建议”。有关此功能的更多信息,请参阅Microsoft Docs。

在C++ Core Guidelines中,检查器在这里使用的具体建议是:ES.103: Don't overflow。

这仅在 x64 中发生的原因是因为size_t64 位而int32 位。在 x86 中,intsize_t都是 32 位。

std::string运算符[]需要size_t。这里最干净最简单的修复是:

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

您还int可以size_t通过在添加之前显式提升to 来解决这个问题:

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

您还可以通过添加以下内容来忽略警告:

#pragma warning(disable : 26451)

或者您可以禁用 C++ 核心指南检查器。


以上是通常的算术转换如何工作?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>