通過退休的工程師代碼排序,我遇到了一個相當簡單的宏,但我的C知識並不是很好。類型鑄造指針解除引用
#define mem32(addr) (*(unsigned long volatile *)(addr))
- 我是否正確這個調用類型轉換指針引用?
- 它類型轉換addr然後解除它?或者相反呢?有關係嗎?
- 命令對於類型限定符和類型說明符是否重要?我曾經假設(在此之前)類型限定符必須位於類型說明符之前,但不一定如此
- 語法問題。第二個*的目的是什麼?
通過退休的工程師代碼排序,我遇到了一個相當簡單的宏,但我的C知識並不是很好。類型鑄造指針解除引用
#define mem32(addr) (*(unsigned long volatile *)(addr))
- 我是否正確這個調用類型轉換指針引用?
是的。
- 它類型轉換爲addr,然後取消它的權限?或者相反呢?有關係嗎?
的*(unsigned long volatile *)(addr)
是類型轉換addr
然後解除引用它。
- 命令對於類型限定符和類型說明符是否重要?
號順序並不重要。 C11部§6.7.2/ 2
[...]可以以任何順序發生的類型說明符,可能 與其他聲明說明符混合。 [...]
演員表(unsigned long volatile *)(addr)
發生在取消引用之前。
不,的單詞的順序unsigned
,long
和volatile
不要緊只要沒有進一步的操作員都混合。 I. e。 volatile int*
和int volatile*
是一樣的,但int * volatile
是不同的。
在高層次上,這個宏的目的是取任何指針,並從該內存地址讀取前四個字節。
然而,這調用不確定的行爲如果這是傳遞給mem32
指針既不是一個指向long
或char
!這是由於嚴格的鋸齒規則。以前的編譯器曾經爲這個宏安全地生成了預期的代碼,但是如果現代編譯器證明類型不匹配,現代編譯器可能只是使用該宏來優化代碼。所以,不要在新代碼中使用它。
謝謝。在volatile類型限定符之後的*怎麼樣?我以前見過,但不明白它的目的。 –
'unsigned long volatile *'是類型*指向'unsigned long volatile int' *的指針的說明符。 – haccks