精度损失(分配)
Loss of precision (assignment)
我的代码(我代码的某些部分)得到以下警告:
# define MN2DIV 0x14
# define PLL_BASE_ADDRESS 0x481C5000
# define ISS_PLL_BASE (PLL_BASE_ADDRESS+0x140)
# define M_PLL (volatile Uint32*)(ISS_PLL_BASE+MN2DIV)
uint16 getfreqmhz(void)
{
uint16 M;
M= *M_PLL;
}
- 注923:从整数转换为指针[MISRA 2004年规则11.3]
- 信息 734:精度损失(赋值)(32 位到 16 位)
我尝试通过这样的转换:M= (uint16)*M_PLL ;
以上更改的原因警告734被删除了,但我认为这不是正确的想法。
有人可以告诉我这样做的正确方法....
这里的关键是你正在与你(大概)有严格规格的硬件接口。
如果MISRA是通用静态分析仪,它将无法识别微控制器环境中的独特保证。你正在做一些C++不太喜欢作为标准的事情,因为它们在(比如)PC上没有意义。但是,有了关于硬件及其接口的足够信息,您的代码在实践中可以完全安全;如果是这样,您可以忽略/禁止显示这些诊断。
-
该注释告诉您有关
(volatile Uint32*)(ISS_PLL_BASE+MN2DIV)
(在宏内部)的信息,您可以在其中从整数形成指针。在任何任意C++程序中,我都会同意MISRA的观点,并说这是不好的形式,但是由于您指定了您知道的实际PLL位置,因此对我来说似乎很好。我自己做。
因此,您可以安全地忽略该注释。
-
"info"是不言自明的:宏建议您将每个寄存器位置视为一个 32 位字,但随后您尝试将该值塞入 16 位。
一些可能性:
- 这是错误的,每个寄存器实际上是 16 位;
getfreqmhz
应返回uint32
;或- 或者,根据对值范围的一些了解,您确定您正在执行的操作是有效的,然后您的强制转换方法就可以了。
您正在从 PLL 读取 32 位值并将其存储在 16 位变量中。有两种情况:
- 您确定从PLL读取的值的最高16位为0。在这种情况下,请忽略警告(如果需要,也可以使用强制转换将其删除),因为您不感兴趣的高阶 0 将自动删除。
- 您对从 PLL 读取的整个 32 位值感兴趣。在这种情况下,
M
应该uint32
能够包含所有这些数据。
关于从整数强制转换为指针的第一个警告适用于托管代码,其中将整数转换为指针毫无意义。在微控制器领域,当您尝试访问映射到固定地址的外设寄存器时,这非常有意义。由于您似乎使用的是微控制器,因此请忽略该警告。
相关文章:
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 精度损失(分配)