2016-08-25 1377 views
1

以下是switch語句的一些代碼。 getvalue()返回unsigned long。 有人可以解釋爲什麼value0xffffffff按位聯繫。 該單元是32位。按位和無符號long與0xffffffff

#define WriteMemory(A,V) *(volatile unsigned long*)(A)=(V) 
static unsigned value; 

case 'b': 
value = getvalue(); 
value &= 0xffffffff; 
WriteMemory(2147455555, value); 
break; 
+0

不,沒有人可以解釋,除非你發佈'值'的變量聲明。 – Lundin

+0

彙編代碼在典型的32位拱形(ILP32)和POSIX 64位拱形(I32LP64)上顯示了哪些優化編譯?你從中得知什麼? – Olaf

+0

@Lundin我已經更新了這個問題。 'value'被聲明爲'static unsigned'。謝謝 – riverrock

回答

6

unsigned long不能保證是C標準的32位。它只能保證能夠保存32位值。

0xffffffff確保32位上的任何位都被清零。

0

代碼用來有時也被稱爲「天真/馬虎打字」,這意味着它將使用標準C的基本intlong類型這些類型是有問題的,往往不可移植的,因爲他們有實現定義大小。

由於實現定義的大小,它們在學習上掩飾掉了低32位,如果int由於某種原因會在某些外來系統上變爲64位。

但是,專業程序總是使用stdint.h的已知大小和簽名類型。專業嵌入式系統尤其如此。

相同的代碼可以在更安全,更便攜的方式被改寫爲:

#include <stdint.h> 

#define WriteMemory(A,V) (*(volatile uint32_t*)(A)=(V)) 
static uint32_t value; 

case 'b': 
value = getvalue(); 
WriteMemory(2147455555, value); 
break; 

uint32_t解決所有問題:不再有任何懷疑的各類有多大,所以這將是完全多餘的面膜低32位。鑑於這是一個32位系統,您也不必擔心隱式類型的促銷活動。

(請注意,在宏觀額外的括號,這是必須避免的經典宏運算符優先級的錯誤,如x = WriteMemory(2147455555, value) + y;錯誤:寫value+y這很可能不是預期的。)

另一個更大的關注這裏雖然是如果給定的系統將允許在地址2147455555處發生未對齊的32位寫入。看起來非常可疑。