首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MISRA C 2012:样本代码中有10.8次违规

MISRA C 2012:样本代码中有10.8次违规
EN

Stack Overflow用户
提问于 2022-03-04 22:23:39
回答 2查看 257关注 0票数 2
代码语言:javascript
运行
复制
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复合表达式的值不应转换为不同的基本类型类别或更广泛的基本类型

描述

规则定义

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-05 10:55:19

这一行代码存在多个问题:

代码语言:javascript
运行
复制
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上的类型胡枝子。您可以使用中间变量output32来存储sint32结果并将其转换为sint32

然而,

  • 这个警告隐藏了一个更重要的问题:规模运算应该被计算为具有足够大的类型来处理A * BA * B / C,而不是使用整数算法的(A / C) * B,在这种整数算法中,渐变会降低精度。

如果已知deltaOutsint16的范围内,您可以编写:

代码语言:javascript
运行
复制
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位算术:

代码语言:javascript
运行
复制
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算法计算浮点内插:

代码语言:javascript
运行
复制
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是什么?它似乎是一个全局变量。您应该避免使用全局变量,特别是使用这样一个平淡的短名称。

票数 1
EN

Stack Overflow用户

发布于 2022-03-05 10:00:08

MISRA C:2012年规则第10.8条规定:

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

查看您的代码:

代码语言:javascript
运行
复制
output = (uint16)( ( ( deltaOut / deltaIn )
                   * ( (sint32)( pcurData->temperature) - (sint32)(pTableData[idx-1].temperature) ) )
                 + (sint32)pTableData[idx-1].Setdata );

让我们看看..。

  • output是一个uint16
  • The,右边是uint16
  • The,右边是sint32

中的复合表达式。

所以:

代码语言:javascript
运行
复制
output = (uint16)( composite expression in sint32 )

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

你有三个选择。

  1. 偏离了
  2. 修改规则,使得outputsint32,是否签名
  3. 中的所有calcs都是无符号的X和M值?是否可以在uint16

uint32中进行计算?

见配置文件

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71357817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档