这两个C函数调用有什么区别?

时间:2016-01-19 05:02:36

标签: c linux

我以两种方式调用以下库函数:

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 *)在第一次调用中使用,它看起来像是指向我的函数指针?

3 个答案:

答案 0 :(得分:3)

指向void的指针是“通用”指针类型。可以将void *转换为任何其他指针类型,而无需显式转换。你不能取消引用void *或用它做指针算术;您必须首先将其转换为指向完整数据类型的指针。请参阅此answer

因此参数pMsg不能直接与lsMsg *兼容,那么第二次调用是一种在函数调用中使用它的可能方法[我没有测试过它]。

顺便说一句,只要pMsg的类型为lsMsg *,第一个就足够了。

编辑:

第二个足以覆盖第一个。

答案 1 :(得分:3)

第二个版本是正确的。

第一个电话看起来像是试图躲避不兼容类型的警告。如果pMsglsMsg *不兼容,您可以通过在其间转换为void*来终止编译器警告。

你不应该这样做,因为它几乎肯定会隐藏你程序中的错误!两种指针类型完全不兼容,在这种情况下程序可能会立即崩溃。访问指针时刻录。或者它们在理论上是兼容的,但是编译器实现了类型别名,然后(void*)强制转换会隐藏违反严格别名规则的行为#34;在任何一种情况下,您都有未定义的行为和严重的错误。

答案 2 :(得分:2)

我认为没有理由第一种方式将指针类型转换两次。只需使用第二种方式即可。