铸造结构* void*

发布于 2025-02-09 05:02:13 字数 557 浏览 2 评论 0原文

我在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)。

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

I have a following function in 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:

"Remove this hazardous cast." (according to MISRA C:2004, 11.2 and 11.3).

Since function message is a 3rd party code, I can't (or shouldn't) change it. 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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉殇 2025-02-16 05:02:13

我认为这是一个长度预备的块。在具有继承的语言中,您将使用类似的内容:

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 );

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

尝试使用工会或What的实施继承会凌乱,它们不会真正增加任何价值。您只需添加代码,因此即将成为一个有效的铸件。

因此,这是一个假阳性。这些是可以从衬里中获得的,因此您应该有一个处理这些处理的过程。

我希望一个过程可以标记某些预期的警告,但是可以使用以下内容进行沉默:

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

message( &msgSPI, 0U )

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

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. 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. This pattern might be wasteful. And it still uses 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.

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. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文