2017-01-02 275 views
1

如何在不寫兩行的情況下直接將「zend_long」賦值給「ptr」?C指針類型鑄造

zend_long *val = *ptr; 
*val = *(ISC_LONG*)var->sqldata; 
+1

'ptr'的類型??? –

+0

它作爲一個funstion參數:「char ** ptr」 實際上它只是一個存儲緩衝區 – Marcodor

+1

除非它們是_compatible types_,否則會調用未定義的行爲。 – Olaf

回答

3

假設你原來的代碼是正確的,相應的分配是這樣的:

*((zend_long*)*ptr) = *(ISC_LONG*)var->sqldata; 
+1

它的作品,非常感謝! – Marcodor

+0

由於嚴格的別名違規,這很可能會調用未定義的行爲。除非'zend_long'碰巧與'ISC_LONG'類型兼容。 – Lundin

+0

@Lundin沒錯。這就是爲什麼我寫道,只有原始代碼是正確的,以上纔有效。 – dasblinkenlight

0

指針類型轉換像這些都不是C-良好定義的行爲,除非這兩個結構發生兼容類型。也就是說,他們必須以相同的順序擁有相同的成員。

如果他們沒有這一點,那麼不幸的是沒有簡單的方法C.做到這一點如果你以某種方式設法得到它的「工作」,它僅僅是運氣不好 - 你的代碼可能隨時崩潰由於未定義的行爲。

這是因爲這樣的演員違反了所謂的strict aliasing rule。例如,您必須通過將結構包裝到聯合類型中來躲避該規則。

+0

感謝您提供有用的信息。我也不喜歡過度投射。但在這種情況下,這是「強制執行」的。 ISC_LONG在這裏定義:https://github.com/FirebirdSQL/firebird/blob/c6d9135586fde54b52e5c26f74d5dfd20c188f3f/src/include/types_pub.h#L111和zend_long在PHP源代碼中具有幾乎相同的定義。所以按價值分配應該是安全的。 – Marcodor

+0

@Marcodor如果它們是相同大小的整數類型,那就很好。如果它們大小不同,或者它們是結構體,那麼就會有問題。 – Lundin