2016-07-23 198 views
2

我目前有一个关于警告的问题。我有一个方法返回一个u8值,其中u8被定义为unsigned charC将无符号字符转换为无符号字符:4

u8 foo (...) 

而且在结构内部我有一个构件x只需要4位。

struct { 
    u8 x : 4; 
    u8 y : 4; 
} s; 

现在我想的foo的返回值赋给x。但是,我的编译器会通过从unsigned charunsigned char : 4的转换,引发可能丢失的警告。然而,这样的演员阵容并未得到承认。

struct_inst.x = (u8 : 4)foo(..); 

这是什么适当的语法?

+0

您不能像这样在类型转换中表示位宽。尝试使用位掩码来代替:'struct_inst.x = foo(..)& 0x0F;'。顺便说一句你正在使用哪种编译器? –

+0

警告是正确的。除非编译器知道'foo()'返回的值在0..15范围内,否则隐式转换可能会丢失信息。正如@MortenJensen所建议的,位掩码显式丢弃了高位。 –

+0

该警告不会消失。我修改这样 [代码] walker-> height.current = map_get_tile_level(from_x,from_y)代码和0xF [/代码] ,我使用的devkit亲的GCC – WodkaRHR

回答

4

如果你在中使用的位域类型不是C类型系统中的正确类型,所以你不能在cast中使用它们。

您的编译器警告有点过度,从一个无符号类型到另一个的转换已定义良好。警告的意义是正确的,但是,将8位类型转换为4位字段可能会丢失信息。也许你可以通过使用0xF来确定你的编译器的声音来让你的编译器保持沉默,这样编译器就会看到你愿意抛出更高的位。

BTW:

  • 有一种类型uint8_t<stdint.h>具有您所需的属性。

  • 使用比int窄的类型在大多数情况下不是一个好主意,因为无论如何,它们总是以算术方式提升到int。只有在你获得的几个字节真的值得的时候才使用它们。如果系统中有千兆字节的内存,例如

  • 位域比窄整数类型更有用。
+0

&0xF不会解决问题,因为警告不会消失。 – WodkaRHR

+2

@WodkaRHR,太糟糕了。然后检查您的编译器警告并关闭无符号到无符号转换的警告。或者更好的是避免使用窄类型。 –

+0

+1 Jens Gustedt:我完全因为这个原因停止使用位域,并且因为GCC oftens生成的代码比你自己处理包装更臃肿。我刚刚开始这样做,而不是... –

相关问题