簡體   English   中英

這兩個C函數調用有什么區別?

[英]What is the difference between these two C function calls?

我以兩種方式調用以下庫函數:

unsigned int
LsSendToQ(unsigned int p4Node, const char queueName[4], lsMsg *pMsg,
          unsigned int prio) {

}

第一種方式:

LsSendToQ((unsigned int)0, (const char *)Q_NAME, (lsMsg *)(void *)pMsg, 0) 

第二種方式:

LsSendToQ((unsigned int)0, (const char *)Q_NAME, (lsMsg *)pMsg, 0) 

兩個調用編譯都很好,但哪一個是正確的方法? 為什么在第一次調用中使用(void *) ,它看起來像是一個函數指針給我?

指向void的指針是“通用”指針類型。 void *可以在沒有顯式強制轉換的情況下轉換為任何其他指針類型。 你不能取消引用void *或用它做指針算術; 您必須首先將其轉換為指向完整數據類型的指針。 看到這個答案

因此參數pMsg不能直接與lsMsg *兼容,那么第二次調用是在函數調用中使用它的一種可能方式[我沒有測試過它]。

順便說一句,只要pMsg類型是lsMsg * ,第一個就足夠了。

編輯:

第二個足夠,因為它涵蓋了第一個。

第二個版本是正確的。

第一個調用看起來像是試圖躲避不兼容類型的警告。 如果pMsglsMsg *不兼容, lsMsg *可以通過在兩者之間轉換為void*lsMsg *編譯器警告。

你不應該這樣做,因為它幾乎肯定會隱藏你的程序中的錯誤! 兩種指針類型完全不兼容,在這種情況下程序可能會在訪問指針時立即崩潰和燒毀。 或者它們在理論上是兼容的,但是編譯器實現了類型別名,然后(void*)強制轉換會隱藏違反“嚴格別名規則”的行為。 在任何一種情況下,您都有未定義的行為和嚴重的錯誤。

我認為沒有理由第一種方式將指針類型轉換兩次。 只需使用第二種方式即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM