示例代码中的 MISRA C2012:10.8 违规

发布于 2025-01-11 22:37:17 字数 1117 浏览 2 评论 0原文

typedef struct{
    sint16 temperature;
    uint32 Setdata;
} VariableA;

VariableA TableData[N];

static uint16 linearinterpolation(const currentdata *pcurData,const VariableA* pTableData)
{   /* Declare local variables */
    sint32 deltaOut;
    sint32 deltaIn;
    uint16 output;
    uint16 idx;
    /* DeltaIn of  temperatures. */
    deltaIn = (sint32)(pTableData[idx].temperature) - (sint32)(pTableData[idx-1].temperature);
    /* DeltaOut of  Setdata */
    deltaOut = (sint32)pTableData[idx].Setdata - (sint32)pTableData[idx-1].Setdata;
    /* Division by 0 protection. */
    if (deltaOut == 0)
    {   /* if the division == 0 */
            output = pTableData[idx-1].Setdata;
    }
    else
    {   /*MISRA C:2012 Rule 10.8 */ 
        output =(uint16)((( deltaOut / deltaIn) *((sint32)(pcurData->temperature) - (sint32)(pTableData[idx-1].temperature))) + (sint32)pTableData[idx-1].Setdata );
    }
    return output; 
} 

我不知道如何解决10.8,是否有人可以解释并修复它,非常感谢。


MISRA C:2012 规则 10.8 复合表达式的值不得转换为不同的基本类型类别或更广泛的基本类型
描述
规则定义
复合表达式的值不得转换为不同的基本类型类别或更广泛的基本类型。

typedef struct{
    sint16 temperature;
    uint32 Setdata;
} VariableA;

VariableA TableData[N];

static uint16 linearinterpolation(const currentdata *pcurData,const VariableA* pTableData)
{   /* Declare local variables */
    sint32 deltaOut;
    sint32 deltaIn;
    uint16 output;
    uint16 idx;
    /* DeltaIn of  temperatures. */
    deltaIn = (sint32)(pTableData[idx].temperature) - (sint32)(pTableData[idx-1].temperature);
    /* DeltaOut of  Setdata */
    deltaOut = (sint32)pTableData[idx].Setdata - (sint32)pTableData[idx-1].Setdata;
    /* Division by 0 protection. */
    if (deltaOut == 0)
    {   /* if the division == 0 */
            output = pTableData[idx-1].Setdata;
    }
    else
    {   /*MISRA C:2012 Rule 10.8 */ 
        output =(uint16)((( deltaOut / deltaIn) *((sint32)(pcurData->temperature) - (sint32)(pTableData[idx-1].temperature))) + (sint32)pTableData[idx-1].Setdata );
    }
    return output; 
} 

I have no idea to solve 10.8, does someone can explain and fix it, thank you very much.


MISRA C:2012 Rule 10.8
The value of a composite expression shall not be cast to a different essential type category or a wider essential type
Description
Rule Definition
The value of a composite expression shall not be cast to a different essential type category or a wider essential type.

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

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

发布评论

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

评论(2

心在旅行 2025-01-18 22:37:17

这行代码存在多个问题:

output = (uint16)(((deltaOut / deltaIn) * ((sint32)(pcurData->temperature) - (sint32)(pTableData[idx-1].temperature))) + (sint32)pTableData[idx-1].Setdata);
  • MISRA C:2012 规则 10.8 规定,不应将复合表达式的值转换为不同的基本类型类别或更广泛的基本类型:复合表达式是整个插值表达式,不同的基本类型是 uint16,它可能是 unsigned Short 上的 typedef。您可以使用中间变量 output32 来存储 sint32 结果并将其转换为 output = (uint16)output32;

  • 然而,这个 MISRA 警告隐藏了一个更重要的问题:缩放操作应计算为 A * B / C,其类型足够大以处理 A * B >,而不是使用整数算术的 (A / C) * B,其中路由会降低精度。

如果 deltaOut 已知在 sint16 范围内,您可以这样写:

sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
sint32 adjust32 = deltaOut * deltaTemp / deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + adjust32;
output = (uint16)output32;

否则,您可能需要 64 位算术:

sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
sint64 adjust64 = (sint64)deltaOut * (sint64)deltaTemp / (sint64)deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + (sint32)adjust64;
output = (uint16)output32;

如果目标具有快速浮点硬件,您可以可以使用 floatdouble 算术计算浮点插值:

sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
double adjust64 = (double)deltaOut * (double)deltaTemp / (double)deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + (sint32)adjust64;
output = (uint16)output64;

根据经验,避免长表达式,为中间结果定义变量并仔细选择其类型以避免溢出或精度损失。

另外一点:你的函数中的 idx 是什么?它似乎是一个全局变量。您应该避免全局变量,尤其是使用这样一个乏味的短名称。

There are multiple problems in this line of code:

output = (uint16)(((deltaOut / deltaIn) * ((sint32)(pcurData->temperature) - (sint32)(pTableData[idx-1].temperature))) + (sint32)pTableData[idx-1].Setdata);
  • MISRA C:2012 Rule 10.8 states that you should not cast the value of a composite expression to a different essential type category or a wider essential type: the composite expression is the whole interpolation expression and the different essential type is uint16, which is probably a typedef on unsigned short. You could use an intermediary variable output32 to store the sint32 result and cast that as output = (uint16)output32;.

  • Yet this MISRA warning is hiding a much more important problem: the scale operation should be computed as A * B / C with a type large enough to handle A * B, not (A / C) * B using integer arithmetics where rouding will reduce the precision.

If deltaOutis known to be in the range of sint16, you could write:

sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
sint32 adjust32 = deltaOut * deltaTemp / deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + adjust32;
output = (uint16)output32;

Otherwise, you might need 64-bit arithmetics:

sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
sint64 adjust64 = (sint64)deltaOut * (sint64)deltaTemp / (sint64)deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + (sint32)adjust64;
output = (uint16)output32;

If the target has fast floating point hardware, you could compute the interpolation in floating point with float or double arithmetics:

sint32 deltaTemp = (sint32)pcurData->temperature - (sint32)pTableData[idx-1].temperature;
double adjust64 = (double)deltaOut * (double)deltaTemp / (double)deltaIn;
sint32 output32 = pTableData[idx-1].Setdata + (sint32)adjust64;
output = (uint16)output64;

As a rule of thumb, avoid long expressions, define variables for intermediary results and choose their type carefully to avoid overflow or precision loss.

Another remark: what is idx in your function? It seems to be a global variable. You should avoid global variables, especially with such a bland short name.

终止放荡 2025-01-18 22:37:17

MISRA C:2012 规则 10.8 规定:

复合表达式的值不得转换为不同的值
基本类型类别或更广泛基本类型

查看您的代码:

output = (uint16)( ( ( deltaOut / deltaIn )
                   * ( (sint32)( pcurData->temperature) - (sint32)(pTableData[idx-1].temperature) ) )
                 + (sint32)pTableData[idx-1].Setdata );

让我们看看...

  • output 是一个 uint16
  • 右侧被转换为uint16
  • 右侧是 sint32 中的复合表达式

因此:

output = (uint16)( composite expression in sint32 )

是的,您没有因为宽度而违反了准则 R.10.8 - 您正在投射到较窄类型;但是,您在复合表达式中将 signed 转换为 unsigned 是违法的。

您有三个选择...

  1. 偏离规则
  2. 修改,使 outputsint32 并以有符号形式进行所有计算
  3. X 和 M 值是否都是无符号的?可以用uint32uint16进行计算吗?

查看个人资料

MISRA C:2012 Rule 10.8 states:

The value of a composite expression shall not be cast to a different
essential type category or a wider essential type

Looking at your code:

output = (uint16)( ( ( deltaOut / deltaIn )
                   * ( (sint32)( pcurData->temperature) - (sint32)(pTableData[idx-1].temperature) ) )
                 + (sint32)pTableData[idx-1].Setdata );

Lets see...

  • output is a uint16
  • The right hand side is cast to uint16
  • The right hand side is a composite expression in sint32

So:

output = (uint16)( composite expression in sint32 )

Yes, you are NOT violating the guideline R.10.8 because of width - you are casting to a narrower type; however you are violating by casting signed to unsigned within the composite expression.

You have three choices...

  1. Deviate the rule
  2. Modify so that output is sint32 and do all calcs in signed
  3. Are the X and M values all unsigned? Could the calculation be performed in uint32 or uint16?

See profile

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