通过使用visual studio如何解决,在c ++中将负常量转换为无符号类型错误

时间:2016-04-19 08:56:57

标签: c++ visual-studio-2012 type-conversion

我的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);
 }

2 个答案:

答案 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仍然被转换为无符号积分。