从'int'转换为'unsigned char'可能会改变其值

时间:2014-02-26 12:51:25

标签: c gcc casting

如果没有明确的(=丑陋的)演员,你将如何删除gcc -Wconversion对以下代码产生的警告:

int main()
{
  int val;
  unsigned char c1 = (val % 65536) / 256;
  unsigned char c2 = (val % 65536) % 256;
}

有没有办法告诉编译器显然在(% 65536) / 256% 256

期间隐含地执行了强制转换

供参考

$ gcc -Wconversion w.c
w.c: In function ‘main’:
w.c:4:36: warning: conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]
w.c:5:36: warning: conversion to ‘unsigned char’ from ‘int’ may alter its value [-Wconversion]

4 个答案:

答案 0 :(得分:6)

使用静态强制转换(或将结果转换为unsigned char)

int main()
{
    int val;
    unsigned char c1 = (unsigned char)((val % 65536) / 256);
    unsigned char c2 = (unsigned char)(val % 256);
}

这会切断警告,因为它基本上告诉编译器,“等等,我的意思是这样做。”

如果您打算不使用签名的VALUES,那么应该从以下开始:

unsigned int val;

而不是:

int val;

即使这样做,你也需要从unsigned int到unsigned char的转换,因为编译器最终仍然会认为你并不想按照你的方式进行下转换。

答案 1 :(得分:3)

听起来你想要这些结果:

c1 = (val >> 8) & 0xff;
c2 = val & 0xff;

修改

来自gcc wiki:Wconversion

  

警告可能会改变值的隐式转换。这包括实数和整数之间的转换,如x为double时的abs(x);有符号和无符号之间的转换,如无符号ui = -1;和转换为较小的类型,如sqrtf(M_PI)。不要警告显式转换,如abs((int)x)和ui =(unsigned)-1,或者如果转换没有像abs(2.0)那样改变值。可以使用-Wno-sign-conversion禁用有关有符号和无符号整数之间转换的警告。对于C ++,还要警告NULL和非指针类型之间的转换;混淆用户定义转换的重载决策;和永远不会使用类型转换运算符的转换:转换为void,相同类型,基类或对它们的引用。默认情况下,在C ++中禁用有符号和无符号整数之间的转换警告,除非明确启用了-Wsign-conversion。

如果val为unsigned,则不会发出警告,但您必须确定要为负值获取的内容。

答案 2 :(得分:0)

因为int是有符号的而char不是,如果因为two's complement而int是负值,这可能会引起混淆。只需在文字附近添加U并将unsigned添加到int中,您也将修复代码,因为实际上val从-32768变为32767(已签名)而不是从0到65536(无符号)

答案 3 :(得分:0)

警告告诉您在所有情况下都没有定义您正在做的事情。如果val为负数,则'%'可能会返回否定结果,并且将该值设置为unsigned char未定义。另请参阅this question

要么确保val永远不会消极并接受警告(每次检查时都没有更改!),或者声明unsigned int