【问题标题】:how to cast typedef struct to uint8_t argument如何将 typedef struct 转换为 uint8_t 参数
【发布时间】:2018-12-03 20:50:11
【问题描述】:

我有一个定义的函数:

uint32_t match_data(uint8_t * data_in, uint16_t size_data_in);

我尝试使用以下 typedef 结构作为参数的地方

typedef struct
{
uint8_t chars[5]
uint8_t ADC;
}Data

Data input;

input.chars[0] = 65;
input.chars[1] = 66;
input.chars[2] = 67;
input.chars[3] = 68;
input.chars[4] = 69;
input.ADC = 255;

match_data((uint8_t *)input, sizeof(input)); 

match_data() 函数返回需要算术或指针类型的“数据”类型的操作数

如何将 typedef 结构转换为 uint8_t?如果我用它作为参考,我会得到同样的错误

如果我只使用 char 数组,我可以直接转换它,但在使用 typedef 结构时不能

【问题讨论】:

  • match_data((uint8_t *) &input, sizeof(Data));

标签: c casting typedef


【解决方案1】:

您需要转换结构对象的地址,而不是结构对象本身:

match_data((uint8_t *)&input, sizeof(input));

这是可行的,因为对象的地址保证与第一个成员的地址相同(即chars)。

但是请注意,通过这样的指针访问其他数据成员(即ADC)是不安全/未定义的行为。这是因为编译器可能会在成员之间引入填充字节,并且访问这样的填充区域是未定义的行为(因为填充区域处于不确定状态;例如,参见 online C standard draft):

J.2 未定义行为 ...具有自动存储期限的对象的值在不确定时使用。

所以实际上我会说你应该直接传递chars

match_data(input.chars, sizeof(input.chars));

【讨论】:

  • 非常感谢您的帮助,如果我保留 4 个字节的倍数,它仍然不安全吗?我正在使用向对象添加更多成员,并且它目前工作得很好
  • 有点晚,但可能对其他人有所帮助。实际上,编译器可能会添加填充字节。您可以在结构定义中使用 __attribute__((packed)) 来建议编译器不要添加填充字节。
猜你喜欢
  • 2022-11-10
  • 2011-10-29
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 2012-05-03
  • 2019-10-14
  • 2021-10-09
相关资源
最近更新 更多