我的C ++程序在dev c ++编译器上运行良好。但是现在我想在visual studio 2013上运行win32控制台,但是我收到一个错误:负常量转换为无符号类型
你能告诉我如何解决它吗?
void modifystudent(int id)
{
fstream file;
file.open("users11.txt",ios::in | ios::out);
student obj;
system("cls");
while (file.read((char*)&obj, sizeof(obj)))
{
if (obj.givid() ==id)
{
cout << "\nPlease enter new details of student";
obj.getrecord(); //// error is here negative constant converted to unsigned type
int pos = -1 * sizeof(obj);
file.seekp(pos, ios::cur);
file.write((char*)&obj, sizeof(obj));
cout << endl << " Record is Modified.." << endl;
}
}
file.close();
// free(obj);
}
答案 0 :(得分:2)
简单地替换
int pos = -1 * sizeof(obj);
通过
int pos = -1 * (int)sizeof(obj);
答案 1 :(得分:2)
gcc和VS都在这里发出警告。您在VS下遇到错误的原因是您可能已启用/WX
选项,该警告将警告视为错误。简单的解决方案是在乘法之前将sizeof(obj)
转换为int:
int pos = -1 * static_cast<int>(sizeof(obj));
更长的解释:
在这个表达式中:
int pos = -1 * sizeof(obj);
-1
的类型为int
,而sizeof(obj)
的类型为size_t
,我们对size_t
的所有了解都是无符号整数 - I假设它主要是4或8字节宽。在进行乘法运算之前,编译器会尝试将两个操作数转换为通用类型,这些转换是隐式的。
现在适用于此处适用的转换规则:当有符号整数与无符号相乘,且无符号操作数与带符号操作数的操作数相同或更大时,带符号操作数将转换为无符号操作数。
因此,如果sizeof(int)
为4个字节,sizeof(size_t)
为8个字节,则-1
首先转换为static_cast<size_t>(-1)
,等于0xffffffffffffffff
。然后进行乘法,然后应用另一个转换 - 乘法的结果转换为int。因为sizeof(obj)
在编译时是已知的,所以编译器将知道确切的值,如果sizeof(obj)
为1,则乘法的结果为0xffffffffffffffff
且其太大而无法分配给int
变量没有截断,因此编译器会警告您所需的隐式转换。
根据size_t
大小,编译器会在此处给出不同的警告:
clang通知乘法结果转换为int的最后阶段(x64编译,sizeof(size_t)== 8):
main.cpp:15:17: warning: implicit conversion from 'unsigned long' to 'int' changes value from 18446744073709551615 to -1 [-Wconstant-conversion]
int pos = -1 * sizeof(obj);
~~~ ~~~^~~~~~~~~~~~~
(18446744073709551615是0xffffffffffffffffff)
gcc看起来很相似,但信息量较少(x64编译,sizeof(size_t)== 8):
main.cpp:16:29: warning: overflow in implicit constant conversion [-Woverflow]
int pos = -1 * sizeof(obj);
另一方面,Visual Studio 2015警告将-1转换为无符号类型(在x86 build中,sizeof(size_t)== 4):
warning C4308: negative integral constant converted to unsigned type
我想它会通知这次转化static_cast<size_t>(-1)
。
和x64(sizeof(size_t)== 8)关于截断常量值(与上面的gcc和clang显示相同的警告)
warning C4309: 'initializing': truncation of constant value
但由于某种原因C4308不再显示,即使tho -1仍然被转换为无符号积分。