通常的算术转换如何工作?
我在 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 中,int和size_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++ 核心指南检查器。