使用0xffffffff按位和无符号长
下面是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;
unsigned long
不保证是C标准的32位。 它只能保证能够保存32位值。
并使用0xffffffff
确保将32位上的任何位清零。
代码使用有时被称为“天真/草率类型”的东西,这意味着它使用标准C中的基本int
和long
类型。这些类型是有问题的并且通常是不可移植的,因为它们具有实现定义的大小。
由于实现定义的大小,他们迂腐地屏蔽了低32位,以防int
由于某种原因在某些奇异系统上变为64位。
但是,专业程序始终使用stdint.h
中已知大小和签名的类型。 对于专业嵌入式系统尤其如此。
可以用更安全和可移植的方式重写相同的代码:
#include #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;
Bug:写入value+y
,这可能不是预期的。)
这里另一个更大的问题是,如果给定的系统允许在地址2147455555处进行错位的32位写操作。看起来非常可疑。