[应用相关] union的使用及一个缺陷

[复制链接]
 楼主| laocuo1142 发表于 2021-4-12 09:35 | 显示全部楼层 |阅读模式
不知道大家在写程序的时候用不用union,之前我只拿来当前后相关性非常强的define来用,有时也和书上一样,存储绝对不会一起出现的值。
之前看M4的SIMD指令时发现很多操作涉及到数据的封装,把两个16位数值放到一个32位变量的高位和低位里。开始的想法是写个16位数组然后强制类型转换为32位读出。后来看了《C专家编程》,发现可以这么写

  • union simdq{
  •     int32_t data;
  •     int16_t dbyte[2];

复制代码

以下是PC测试程序(同时给2个数乘2,我随便想的一个),也通过32试验
  • #include <stdio.h>
  • #include <stdint.h>
  • int
  • main(int argc,char * argv[]){
  •     union simdq{
  •         int32_t data;
  •         int16_t dbyte[2];
  •     }test;
  •     test.dbyte[0]=1234;
  •     test.dbyte[1]=-5678;
  •     printf("test.dbyte[0]= %x\ntest.dbyte[1]= %x\n",test.dbyte[0],test.dbyte[1]);
  •     printf("test.data    = %x\n",test.data);
  •     test.data*=2;
  •     printf("test.dbyte[0]= %x\ntest.dbyte[1]= %x\n",test.dbyte[0],test.dbyte[1]);
  •     printf("test.data    = %x\n",test.data);
  •     return 0;
  • }

复制代码

返回
  • test.dbyte[0]= 1234
  • test.dbyte[1]= -5678
  • test.data    = -372112174
  • test.dbyte[0]= 2468
  • test.dbyte[1]= -11356
  • test.data    = -744224348

复制代码


如果使用16进制,则需要把类型改成 unsigned int ,否则若最高一位为1,读取值会自动扩展(用printf和%x看起来似乎是这样(而且无法通过强制类型转换解决(例如dbyte[1]=0xFFFFACF0(期望值应该是0xACF0(非常诡异(希望高手解答(也是和大家交流分享知识)))))))

MCU:STM32F401 + Keil v5
PC   :Intel core     + clang 3.7.0

duo点 发表于 2021-4-12 09:47 | 显示全部楼层
一点都不诡异,要想用union实现16位操作对32位数的MSW和LSW的存取,只能用16位无符号数,如此定义:
uint16_t  dword[2];
int32_t    data;
一刀一级 发表于 2021-4-12 09:48 | 显示全部楼层

是的,这里面涉及到对齐的问题。
七毛钱 发表于 2021-4-12 09:48 | 显示全部楼层
这个想法很好,但是我从来没有这方面的想法
diweo 发表于 2021-4-12 14:32 | 显示全部楼层
哪里诡异了,结果不都正常的么?
晓伍 发表于 2021-5-7 09:17 | 显示全部楼层
自己没用过啊
八层楼 发表于 2021-5-7 10:17 | 显示全部楼层
只是他的一个特点吧
观海 发表于 2021-5-7 10:20 | 显示全部楼层
一定要注意对齐的方式
guanjiaer 发表于 2021-5-7 10:22 | 显示全部楼层
注意一下就可以了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1296

主题

6236

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部

1296

主题

6236

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部