2016-07-23 244 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生成的代碼比你自己處理包裝更臃腫。我剛剛開始這樣做,而不是... –

相關問題