繁体   English   中英

将 struct* 转换为 void*

[英]Casting struct* to void*

我在 C 中有以下函数:

Bool message(void* msg, unsigned timeout);

以及我想传递给该函数的结构:

msgSPI_t msgSPI; //msgSPI_t is of struct type

像这样:

message(&msgSPI, (unsigned)0)

现在,这可以按预期工作,但是由于我使用 SonarQube 进行代码质量检查,因此我遇到了传递&msgSPI的错误:

“移除这个危险的演员表。” (根据 MISRA C:2004、11.2 和 11.3)。

由于函数message是第 3 方代码,我不能(或不应该)更改它。 这里有什么好的解决方案,可以满足声纳投诉? (在&msgSPI前面添加(void*)可以清除错误,但我不确定这是否是正确的方法。)

我认为这是一个以长度为前缀的块。 在具有继承的语言中,您将使用如下内容:

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没有继承。 相反,你倾向于看到

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

但这需要message来构建消息,可能涉及内存分配。 这种模式可能很浪费。 它仍然使用void *

尝试使用联合或诸如此类的东西来实现继承会很麻烦,而且它们不会真正增加任何价值。 您只需添加代码,从而增加复杂性,最终得到实际上只是一个演员表的东西。

所以这是一个误报。 这些是 linter 预期的,所以你应该有一个处理这些的过程。

我更喜欢标记某些预期警告的过程,但可以使用以下方法使其静音:

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

message( &msgSPI, 0U )

我强烈建议不要在每次使用message的呼叫站点使用演员表。 指针强制转换是危险的,因为它违反了类型系统。 以上确实有演员表,这就是为什么它不是我的首选方法。 但它只是一个位置,因此更容易管理。

暂无
暂无

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

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