使用0xffffffff按位和无符号长整数

时间:2016-08-25 10:40:59

标签: c bit-manipulation

以下是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; 

2 个答案:

答案 0 :(得分:6)

unsigned long不能保证是C标准的32位。它只能保证能够保存32位值。

并使用0xffffffff确保将32位上的任何位清零。

答案 1 :(得分:0)

代码使用有时被称为"天真/草率类型",这意味着它使用标准C中的基本intlong类型。这些类型是有问题且通常是不可移植的,因为它们具有实现定义的大小。

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