Синтаксическая ошибка в битовой упаковке структуры в C после переключения компилятора и IDE

Ладно, чего мне не хватает....

Первоначально я написал код на IAR IDE/компиляторе для использования на микропроцессоре ARM, и он работал нормально.

Сейчас мы переходим на другой контроллер с микропроцессором Tricore и теперь используем IDE code::blocks с компилятором GNU GCC для TriCore v3.4.6.

При построении я получаю ошибки с двумя приведенными ниже структурами (связанные перечисления приведены для справки):

01| typedef enum equip_states_t {
02|   stopped = 0,
03|   starting = 1,
04|   running = 2,
05|   paused = 3,
06|   stopping = 4
07| }equip_states_t;
08| 
09| typedef enum info_level_t{
10|   clear = 0,
11|   alert = 1,
12|   warning = 2,
13|   error = 3
14| } info_level_t;
15| 
16| typedef struct d2101_equip_states_t {
17|   equip_states_t        AIR_COMP_state:4; //Error starts here
18|   pause_states_t        auto_pause_state:4;
19|   fullness_states_t     BE_fullness:4;
20|   equip_states_t        BE_state:4;
21|   fullness_states_t     BIN_fullness:4;
22|   bin_states_t          BIN_state:4;
23|   bin_states_t          BYPASS_state:4;
24|   control_modes_t       control_mode:4;
25|   equip_states_t        DC_state:4;
26|   source_dest_t         DIV_auto_pause:4;
27|   source_dest_t         DIV_position:4;
28|   equip_states_t        HYDR_state:4;
29|   equip_states_t        QL_state:4;
30|   fullness_states_t     TC_fullness:4;
31|   equip_states_t        TC_state:4;
32|   equip_states_t        TUC_state:4;
33| } d2101_equip_states_t;
34| 
35| typedef struct info_message_t {
36|   uint16_t              ID;  //Error starts here
37|   info_level_t          status:8;
38|   uint8_t               not_used;
39|   uint32_t              time_stamp:32;
40| } info_message_t;

Ошибки:

[18] error: [11705] syntax error before "pause_states_t"
[18] warning: [11407] no semicolon at end of struct or union
[19] error: [11707] syntax error before ':' token
[20] error: [11707] syntax error before ':' token
[21] error: [11707] syntax error before ':' token
[24] error: [11707] syntax error before ':' token
[25] error: [11707] syntax error before ':' token
[26] error: [11707] syntax error before ':' token
[27] error: [11707] syntax error before ':' token
[28] error: [11707] syntax error before ':' token
[29] error: [11707] syntax error before ':' token
[30] error: [11707] syntax error before ':' token
[31] error: [11707] syntax error before ':' token
[32] error: [11707] syntax error before ':' token
[33] warning: [13263] type defaults to 'int' in declaration of 'd2101_equip_states_t'
[33] warning: [10516] data definition has no type or storage class
[37] error: [11705] syntax error before "info_level_t"
[37] warning: [11407] no semicolon at end of struct or union
[39] error: [11707] syntax error before ':' token
[40] warning: [13263] type defaults to 'int' in declaration of 'info_message_t'
[40] warning: [10516] data definition has no type or storage class

ОДНАКО... Во многих, многих других случаях, включая некоторые до и после в одном и том же файле, я использую один и тот же синтаксис без ошибок и, следовательно, не понимаю, что происходит не так. НАПРИМЕР.

typedef struct rmt2001_feedback_to_remote_t{
  uint8_t               screen_number;
  bool                  fault_present:1;
  switch_states_t       DC:1;
  switch_states_t       air:1;
  switch_states_t       HYDR:1;
  switch_states_t       TUC:1;
  switch_states_t       BE:1;
  switch_states_t       TC:1;
  switch_states_t       green_backlight:1;
  source_dest_t         dest:3;
  equip_states_t        status:3;
  switch_states_t       red_backlight:1;
  switch_states_t       blue_backlight:1;
  uint8_t               gate_percent;
  uint8_t               bin_percent;
  uint8_t               BE_amps_msb;
  uint8_t               BE_amps_lsb;
  uint8_t               not_used;
} rmt2001_feedback_to_remote_t;

typedef struct IO_view_t{
  master_or_slave_t     master_or_slave:1;
  uint8_t               exponent:3;
  uint8_t               controller_id:4;
  uint8_t               io_id:6;
  A_of_D_t              A_or_D:1;
  I_or_O_t              I_or_O:1;
  uint16_t              raw;
  int16_t               value;
} IO_view_t;

Если я правильно помню, то, что я читал в другом месте на этом сайте, заключается в том, что упаковка битов структуры не очень согласуется между компиляторами, поскольку она не четко/строго определена стандартом c. Я также читал, что использование побитовых операций с масками и смещениями является более удобным для разных платформ способом упаковки битов и отказа от чего-либо еще, что я могу сделать.... Но я хочу знать, почему это не работает только в этих двух случаях. и я надеюсь, что есть какая-то простая мелочь, которая избавит меня от необходимости делать это.

Спасибо всем за потраченное время на чтение этого.


person MidnightRover    schedule 20.03.2019    source источник
comment
Вероятно, они не разрешают битовые поля на основе enum, просто так. Вы можете попытаться выбросить их и использовать uint32_t или uint8_t. Также убедитесь, что вы компилируете с -std=c11.   -  person Lundin    schedule 20.03.2019
comment
Используете ли вы одни и те же флаги компилятора? Какие?   -  person Christian Gibbons    schedule 20.03.2019
comment
Чтобы опираться на комментарий @Lundin, когда я компилирую с помощью gcc (с -std=c99 или -std=c11) с педантичными предупреждениями, я получаю warning: type of bit-field '<name of field>' is a GCC extension для всех битовых полей типов перечисления.   -  person Christian Gibbons    schedule 20.03.2019
comment
Спасибо @Lundin и @christian-gibbons за ваши быстрые ответы, но оказалось, что компилятор обрабатывал pause_states_t и info_level_t как пробелы, потому что их определение типа еще не было прочитано. Спасибо еще раз   -  person MidnightRover    schedule 20.03.2019


Ответы (1)


И ответ таков... это связано с порядком чтения typedef структурных типов данных между двумя компиляторами и/или из-за незначительных структурных изменений в программе из-за другого контроллера.

Если я перемещу typedef pause_states_t и info_level_t в другой файл, который определенно читается перед этим файлом, ошибка исчезнет.

Похоже, что вместо того, чтобы получить какую-то ошибку «непризнанный символ» или «непризнанный тип данных», он обрабатывает ее как пустую, и именно это вызывает ошибки.

Это согласуется с некоторыми другими ошибками, которые я получаю сейчас, когда компилятор сталкивается с пользовательскими типами данных до того, как будет прочитано typedef.

person MidnightRover    schedule 20.03.2019