使用0xffffffff按位和无符号长

下面是switch语句中的一些代码。 getvalue()返回unsigned long 。 有人可以解释为什么value0xffffffff 。 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中的基本intlong类型。这些类型是有问题的并且通常是不可移植的,因为它们具有实现定义的大小。

由于实现定义的大小,他们迂腐地屏蔽了低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位写操作。看起来非常可疑。