есть ли опция gcc для устранения этой проблемы, связанной с битовым полем C?

#c #gcc #bit-fields

#c #gcc #битовые поля

Вопрос:

Мой код нравится ниже, но после компиляции gcc вывод этой процедуры всегда «не соответствует».

Кажется, что RXC_SLOT всегда имеет 8-битную ширину в этом коде, а не 6. Почему?

 #include <stdint.h>
#include <stdio.h>

typedef struct _RX_CONROL_t {
    union {
        struct {
            //32'b{RESERVED12, RX_ABORT, RXC_RECEIVE, RXC_SOURCE_PORT, RXC_SLOT}
            //32'b{     20bit,     1bit,        1bit,            4bit,     6bit}
             uint8_t RXC_SLOT         : 6;
             uint8_t RXC_SOURCE_PORT  : 4;
             uint8_t RXC_RECEIVE      : 1;
             uint8_t RX_ABORT         : 1;
             uint32_t RESERVED12       : 20;
        };
        uint32_t VALUE32;
    };
} RX_CONROL_t;

int main(void) {

    RX_CONROL_t rx_control = {.VALUE32 = 0};

    rx_control.RXC_SLOT = 3;
    rx_control.RXC_SOURCE_PORT = 2;
    rx_control.RXC_RECEIVE = 1;
    rx_control.RX_ABORT = 0;
    //32'b{RESERVED12, RX_ABORT, RXC_RECEIVE, RXC_SOURCE_PORT, RXC_SLOT}
    //32'b{     20'd0,     1'd0,        1'b1,            4'd2,     6'd3} == 32'h00000483
    if(rx_control.VALUE32 == 0x00000483) {
        printf("matchn");
        return 0;
    }
    else {
        printf("unmatch rx_control.VALUE32 is %xn", rx_control.VALUE32); //FIXME: rx_control.VALUE32 is 1203 (why?)
        printf("%x %x %x %x %xn", rx_control.RXC_SLOT, rx_control.RXC_SOURCE_PORT, rx_control.RXC_RECEIVE, rx_control.RX_ABORT, rx_control.RESERVED12);
        return 1;
    }
}
  

Комментарии:

1. Потому что вы сказали, что это uint8_t . Попробуйте сделать это uint32_t . Или, возможно, используйте битовые маски вместо битовых полей.

2. @n.’местоимения’m.спасибо, но RXC_SOURCE_PORT, RXC_RECEIVE, RX_ABORT имеют правильную разрядность. Неправильная разрядность RXC_SLOT переводит другие поля в более высокое положение. Изначально я думал, потому что ‘RXC_SLOT RXC_SOURCE_PORT’ имеет ширину 6 4 = 10 бит, которая превышает границу uint8_t, поэтому компилятор запускает новую область для RXC_SOURCE_PORT .

3. Поскольку uint32_t битовые поля должны храниться отдельно от uint8_t битовых полей, в первых 4 битовых полях перед uint32_t битовым полем есть 4 бита заполнения. Создайте их все uint32_t , и они смогут использовать один и тот же блок хранения.

4. uint32_t работает хорошо, спасибо!!

5. Вы в принципе правы: 6 4 бита не вписываются в ваш uint8_t , и поэтому второе поле помещается в следующий элемент типа uint8_t . Битовые поля обычно не хранятся в границах unterlying типа. Но, конечно, поскольку они в любом случае определены реализацией, я не был бы слишком удивлен, если бы это сделал компилятор…