首页 > 解决方案 > 切换编译器和 IDE 后,在 C 中位打包结构时出现语法错误

问题描述

好吧,我错过了什么......

我最初在 IAR IDE/编译器上编写了代码,用于 ARM 微处理器,它运行良好。

我们现在正在切换到带有 Tricore 微处理器的不同控制器,并且现在正在使用 code::blocks IDE 和用于 TriCore v3.4.6 的 GNU GCC 编译器。

构建时,我收到以下两个结构的错误(相关枚举供参考):

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 标准定义。我还读到,使用带有掩码和偏移量的按位运算是一种更跨平台友好的方式来进行位打包和失败任何其他我能做到的事情......但我想知道为什么这仅在这两个实例中不起作用我希望有一些简单的小事可以让我不必这样做。

感谢大家花时间阅读本文。

标签: cgccstructbit-packing

解决方案


答案是......它与在两个编译器之间读取结构数据类型 typedef 的顺序和/或由于不同的控制器对程序的微小结构变化有关。

如果我将 typedef 的pause_states_t和移动info_level_t到另一个文件,该文件肯定在该文件之前读取,错误就会消失。

似乎不是得到某种“无法识别的符号”或“无法识别的数据类型”错误,而是将其视为空白,这就是触发错误的原因。

这与我现在遇到的其他一些错误一致,即编译器在读取 typedef 之前遇到客户数据类型。


推荐阅读