简体   繁体   English

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

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

I am calling the following library function in two ways: 我以两种方式调用以下库函数:

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

}

The first way : 第一种方式:

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

and the second way : 第二种方式:

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

Both calls compile fine, but which one is the right way ? 两个调用编译都很好,但哪一个是正确的方法? And why is (void *) used in the first call, which looks like a function pointer to me ? 为什么在第一次调用中使用(void *) ,它看起来像是一个函数指针给我?

A pointer to void is a "generic" pointer type. 指向void的指针是“通用”指针类型。 A void * can be converted to any other pointer type without an explicit cast. void *可以在没有显式强制转换的情况下转换为任何其他指针类型。 You cannot dereference a void * or do pointer arithmetic with it; 你不能取消引用void *或用它做指针算术; you must convert it to a pointer to an complete data type first. 您必须首先将其转换为指向完整数据类型的指针。 See this answer . 看到这个答案

So the parameter pMsg is not directly compitable to lsMsg * then the 2nd calling is a possible way to use this in the function calling[ I didn't tested it]. 因此参数pMsg不能直接与lsMsg *兼容,那么第二次调用是在函数调用中使用它的一种可能方式[我没有测试过它]。

By the way, as long as type of pMsg is lsMsg * the 1st one is enough. 顺便说一句,只要pMsg类型是lsMsg * ,第一个就足够了。

Edit: 编辑:

The 2nd one is enough as it covers the 1st one. 第二个足够,因为它涵盖了第一个。

The second version is the correct one. 第二个版本是正确的。

The first call looks like an attempt to dodge incompatible type warnings. 第一个调用看起来像是试图躲避不兼容类型的警告。 If pMsg is not compatible with lsMsg * you could kill the compiler warning by casting to void* in between. 如果pMsglsMsg *不兼容, lsMsg *可以通过在两者之间转换为void*lsMsg *编译器警告。

You shouldn't do this though, because it almost certainly hides a bug in your program! 你不应该这样做,因为它几乎肯定会隐藏你的程序中的错误! Either the two pointer types are completely incompatible, in which case the program may instantly crash & burn upon accessing the pointer. 两种指针类型完全不兼容,在这种情况下程序可能会在访问指针时立即崩溃和烧毁。 Or they are in theory compatible, but the compiler implements type aliasing and the (void*) cast would then hide a violation of the "strict aliasing rule". 或者它们在理论上是兼容的,但是编译器实现了类型别名,然后(void*)强制转换会隐藏违反“严格别名规则”的行为。 In either case you have undefined behavior and a severe bug. 在任何一种情况下,您都有未定义的行为和严重的错误。

I see no reason for the first way of converting the pointer type twice. 我认为没有理由第一种方式将指针类型转换两次。 Just use the second way is enough. 只需使用第二种方式即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM