简体   繁体   English

将 struct* 转换为 void*

[英]Casting struct* to void*

I have a following function in C:我在 C 中有以下函数:

Bool message(void* msg, unsigned timeout);

and a structure that I want to pass to that function:以及我想传递给该函数的结构:

msgSPI_t msgSPI; //msgSPI_t is of struct type

like so:像这样:

message(&msgSPI, (unsigned)0)

Now, this works as intended, but since I am using SonarQube for code quality inspection, I get a bug for passing &msgSPI :现在,这可以按预期工作,但是由于我使用 SonarQube 进行代码质量检查,因此我遇到了传递&msgSPI的错误:

"Remove this hazardous cast." “移除这个危险的演员表。” (according to MISRA C:2004, 11.2 and 11.3). (根据 MISRA C:2004、11.2 和 11.3)。

Since function message is a 3rd party code, I can't (or shouldn't) change it.由于函数message是第 3 方代码,我不能(或不应该)更改它。 What would be a good solution here, that would satisfy Sonar complaints?这里有什么好的解决方案,可以满足声纳投诉? (adding (void*) in front of &msgSPI clears the bug, but I am not sure if that's the correct way to do this.) (在&msgSPI前面添加(void*)可以清除错误,但我不确定这是否是正确的方法。)

I presume this is a length-prefixed block.我认为这是一个以长度为前缀的块。 In a language with inheritance, you'd use something like this:在具有继承的语言中,您将使用如下内容:

class BaseMessage {
   uint32_t size;
};

class MyMessage extends BaseMessage {
   // ...
};

bool message( BaseMessage *msg, unsigned timeout );

MyMessage my_message;
my_message.size = sizeof( MyMessage );
...

message( &my_message, timeout );

C doesn't have inheritance. C没有继承。 Instead, you tend to see相反,你倾向于看到

bool message( void *msg_body, size_t msg_body_size, unsigned timeout );

But that would require message to build the message, possibly involving a memory allocation.但这需要message来构建消息,可能涉及内存分配。 This pattern might be wasteful.这种模式可能很浪费。 And it still uses void * .它仍然使用void *

Trying to implement inheritance using unions or whatnot would be messy, and they wouldn't really add any value.尝试使用联合或诸如此类的东西来实现继承会很麻烦,而且它们不会真正增加任何价值。 You'd just add code and thus complexity to end up with what is effectively just a cast.您只需添加代码,从而增加复杂性,最终得到实际上只是一个演员表的东西。

So this is a false positive.所以这是一个误报。 These are to be expected from linters, so you should have a process in place to handle these.这些是 linter 预期的,所以你应该有一个处理这些的过程。

I would prefer a process that flags certain warnings expected, but it could maybe be silenced using the following:我更喜欢标记某些预期警告的过程,但可以使用以下方法使其静音:

// Silence SonarQube false positive.
#define message( msg, timeout ) message( (void*)(msg), (timeout) )

message( &msgSPI, 0U )

I would strongly recommend against using a cast at the call site of each use of message .我强烈建议不要在每次使用message的呼叫站点使用演员表。 Pointer casts are dangerous as the defy the type system.指针强制转换是危险的,因为它违反了类型系统。 The above does have a cast, which is why it's not my preferred approach.以上确实有演员表,这就是为什么它不是我的首选方法。 But it's only one location, so it's more easily managed.但它只是一个位置,因此更容易管理。

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

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