2013-10-08 34 views
1

讓我們假設,我有以下結構:應該鑄造用於設置位域?

struct my_struct { 
    uint32_t bf1 : 3; 
    uint32_t bf2 : 5; 
    uint32_t bf3 : 16; 
    uint32_t bf4 : 8; 
}; 

及以下枚舉:

enum bf1_values { 
    Val1 = 0x0; 
    Val2 = 0x4; 
    Val3 = 0x7; 
}; 
除了

,getter和setter功能BF1:

uint32_t bf1_getter() { 
    return global_struct.bf1; // cast value to (uint32_t)? 
} 


void bf1_setter(enum bf1_values val) { 
    global_struct.bf1 = val; // cast enum to (uint32_t)? 
} 

我應該使用getter和setter函數中的類型轉換以確保安全?

編輯:

的結構應該被髮送到HW。

EDIT2:

我想實現的是真正確保enum將被正確寫入位域,並從位域正確讀取。

+6

型鑄造無關安全,往往是完全相反。 –

+0

@JoachimPileborg好的,但是這樣的代碼寫作的正常/好的做法是什麼? – Alex

+0

它是否在沒有警告的情況下編譯?然後你不需要投射。否則*你*必須確保代碼是安全的,投射對你沒有幫助(它只會幫助你關閉編譯器警告)。 –

回答

2

無需鑄造在這裏 - 在分配已經「安全」的,只要符合的實現不應損壞其他成員。假設正常的整數溢出語義應用,唯一有問題的情況下籤署的溢出,從而可以提高的信號(但我很難看到這種事情發生在實踐中,如果該位字段寬度是不是一個完整的字作爲harware支持度溢出檢測將會缺失)並且在其他情況下是實現定義的。此警告不適用於您的示例,因爲目標類型未經簽名。

記住位字段的語義在很大程度上實現定義 - 即使使用比int其他類型實際上是一種語言的擴展 - 它是由你來檢查,編譯器做你希望它在所有相關做些什麼平臺。

更便攜,還不太方便的方法是隻需使用一個uint32_t,做手工位擺弄。如果你不需要這種可伸縮性,它應該沒問題。