分配给struct成员的值不正确

时间:2015-07-23 04:23:00

标签: c struct enums bit-fields

我完全不知道这里发生了什么,并且非常想知道。

我有一个枚举:

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编译器。

2 个答案:

答案 0 :(得分:2)

具有rowid_Boolsigned intint以外类型的位字段是不可移植的。

大小为unsigned int的带符号位域可以保存:2的值。由于您似乎获得了这些值,这意味着您的实现正在使这些位字段被签名。

听起来你想要无符号的位域,所以我建议使用-2, -1, 0, 1

NB。在位字段中,它的实现定义unsigned intint还是signed int。因此,如果您使用普通unsigned int,它可能仍会根据编译器或设置提供不同的范围。

答案 1 :(得分:0)

该标准允许编译器扩展位字段。许多人为了更好的表现而这样做编译器实现

非常
     unsigned somefield: 2 ;

为32位。我完全不鼓励使用位域。它们不便携。如果需要特定宽度的位域,最好的方法是使用按位运算符插入和提取。