我完全不知道这里发生了什么,并且非常想知道。
我有一个枚举:
typedef enum
{
TAxCLK = 0,
ACLK,
SMCLK,
INCLK
} TIMER_A_CLOCK_E;
和结构:
typedef struct
{
BYTE byTimerSelection :2;
TIMER_A_CLOCK_E eClockSource :2;
INPUT_DIV_E eInputDivider :2;
TIMER_MODE_E eTimerMode :2;
} TIMER_A_S;
其他最后两个成员的枚举类似于另一个,第一个只是unsigned char
。这个struct
用于初始化微控制器上的寄存器,因此我将每个字段限制为2位。
我指定struct
的成员如此:
TIMER_A_S stTimerInfo;
// Setup Timer A
stTimerInfo.byTimerSelection = 0;
stTimerInfo.eClockSource = SMCLK;
stTimerInfo.eInputDivider = INPUT_DIV_1;
stTimerInfo.eTimerMode = UP;
然而,eClockSource
成员表现得很奇怪。 Code Composer调试器将字段显示为32位而不是2,最后分配给它的值是-2而不是2.经过一些实验,我发现写0会导致它读0并写5来它导致它读2 ...发生了什么?其他成员表现得很好。它是用于32位控制器的TI ARM编译器。
答案 0 :(得分:2)
具有rowid
,_Bool
,signed int
或int
以外类型的位字段是不可移植的。
大小为unsigned int
的带符号位域可以保存:2
的值。由于您似乎获得了这些值,这意味着您的实现正在使这些位字段被签名。
听起来你想要无符号的位域,所以我建议使用-2, -1, 0, 1
。
NB。在位字段中,它的实现定义unsigned int
是int
还是signed int
。因此,如果您使用普通unsigned int
,它可能仍会根据编译器或设置提供不同的范围。
答案 1 :(得分:0)
该标准允许编译器扩展位字段。许多人为了更好的表现而这样做编译器实现
是非常 unsigned somefield: 2 ;
为32位。我完全不鼓励使用位域。它们不便携。如果需要特定宽度的位域,最好的方法是使用按位运算符插入和提取。