以下是switch语句中的一些代码。 getvalue()
会返回unsigned long
。
有人可以解释为什么value
与0xffffffff
按位相加。
mcu是32位。
#define WriteMemory(A,V) *(volatile unsigned long*)(A)=(V)
static unsigned value;
case 'b':
value = getvalue();
value &= 0xffffffff;
WriteMemory(2147455555, value);
break;
答案 0 :(得分:6)
unsigned long
不能保证是C标准的32位。它只能保证能够保存32位值。
并使用0xffffffff
确保将32位上的任何位清零。
答案 1 :(得分:0)
代码使用有时被称为"天真/草率类型",这意味着它使用标准C中的基本int
和long
类型。这些类型是有问题且通常是不可移植的,因为它们具有实现定义的大小。
由于实现定义的大小,它们迂腐地屏蔽了低32位,以防int
由于某种原因在某些奇异系统上变为64位。
但是,专业程序始终使用stdint.h
中已知大小和签名的类型。对于专业嵌入式系统尤其如此。
可以用更安全和可移植的方式重写相同的代码:
#include <stdint.h>
#define WriteMemory(A,V) ( *(volatile uint32_t*)(A)=(V) )
static uint32_t value;
case 'b':
value = getvalue();
WriteMemory(2147455555, value);
break;
uint32_t
解决了所有问题:不再怀疑各种类型有多大,所以用低32位掩码是完全多余的。考虑到这是一个32位系统,你也不必担心隐式类型促销。
(注意宏中的额外括号,这是避免经典宏运算符优先级错误所必需的,例如x = WriteMemory(2147455555, value) + y;
错误:写value+y
这可能不是预期的。)
另一个更大的问题是,如果给定的系统允许在地址2147455555处进行错位的32位写入。看起来非常可疑。