搜索
bottom↓
回复: 24

stm32f103的位域赋值,却影响了整个字节。。大家帮忙看一下

[复制链接]

出0入0汤圆

发表于 2017-7-18 15:19:26 | 显示全部楼层 |阅读模式
本帖最后由 WM_CH 于 2017-7-18 15:27 编辑



如图中的定义,和内存分布。
按说对位域赋值,只会影响位域变量 和 CHAR[0] 共同使用的内容,可是实验结果却是修改了CHAR[0]的非共用内容!!
代码如下:
  1.     tCAN.CHAR[0] = 0x58;
  2.     printf("%#x\r\n", tCAN.CHAR[0]);
  3.     printf("%#x\r\n", tCAN.BIT01);
  4.     printf("%#x\r\n\r\n", tCAN.BIT23);
  5.    
  6.     tCAN.BITbit01 = 0x01;
  7.     printf("%#x\r\n", tCAN.CHAR[0]);
  8.     printf("%#x\r\n", tCAN.BIT01);
  9.     printf("%#x\r\n\r\n", tCAN.BIT23);
复制代码


输出结果是
0x58
0
0x02

0x01
0x01
0


这里红色部分可以看出,影响了整个CHAR[0]字节!!!这个是绝不可能的啊!这什么情况。。。
MDK里面用了一个关键字#pragma anon_union来使用匿名联合(如图中),这个会影响赋值操作?我只是瞎猜。。。





同样的做法,在电脑端用VS2010测试结果是
0x58
0
0x02

0x59
0x01
0x02


这里蓝色部分可以看出,这才是正确的结果啊。。。







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出200入2554汤圆

发表于 2017-7-18 15:30:12 | 显示全部楼层
CHAR 和后边的位域,共处于一个 union 当中,很显然 CHAR[0] 要和位变量共用内存区了,互相影响不应该是正常的么。

不知何来“按说对位域赋值,不会影响CHAR[0]的内容的”一说。

出0入0汤圆

 楼主| 发表于 2017-7-18 15:35:18 | 显示全部楼层
t3486784401 发表于 2017-7-18 15:30
CHAR 和后边的位域,共处于一个 union 当中,很显然 CHAR[0] 要和位变量共用内存区了,互相影响不应该是正 ...

我的意思是说,修改位域那个变量,只会修改CHAR[0]所在的字节中,和位域变量共用的几个bit,
而不应该修改不共用的bit。

如题中,BITbit01只占CHAR[0]最低的两个bit,
赋值BITbit01 = 0x01,【CHAR[0] = 0x58】
那么CHAR[0] 应该等于 0x59
而不是CHAR[0] 也变成了 0x01




出0入0汤圆

发表于 2017-7-18 15:56:03 | 显示全部楼层
本帖最后由 snoopyzz 于 2017-7-18 15:57 编辑

楼主你自己用了union!!

自然是共用了, union里每个成员都是共用的, 你这样定义后BITbit01和BIT01是完全等价的, 与CHAR[0]的低2位也等价

你这别说stm32, 随便放哪个C编译器也是一样的结果, 你自以为是的结果反而是错的

出0入0汤圆

 楼主| 发表于 2017-7-18 16:37:48 | 显示全部楼层
这里有两个概念比较模糊,
第一个是大小端问题,即BITbit01和CHAR[x]形成联合体,x到底是0还是7
第二个是BITbit01和BIT01是完全等价的, 与CHAR[0]的哪2位是等价的?【这个是我没搞清楚,编译器也没搞清楚,导致的楼主的问题出现】
正确办法是,对一个没有用到的空位域,要写明,把整个字节填充满。

所以经过实验,加了个空位域进去填充满字节,输出结果是正确的了。






结贴、

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2017-7-18 22:37:49 来自手机 | 显示全部楼层
WM_CH 发表于 2017-7-18 16:37
这里有两个概念比较模糊,
第一个是大小端问题,即BITbit01和CHAR[x]形成联合体,x到底是0还是7
第二个是BI ...

位域  不跟八位对齐本来就是会纠结死人的  就是普通结构体成员不对齐也会憋死强迫症  要调换成员顺序甚至显性添加空字节对齐2/4

出0入0汤圆

 楼主| 发表于 2017-7-19 09:49:17 | 显示全部楼层
huangqi412 发表于 2017-7-18 22:37
位域  不跟八位对齐本来就是会纠结死人的  就是普通结构体成员不对齐也会憋死强迫症  要调换成员顺序甚至 ...

谢谢大哥的扩展提示,原来不管是位域、还是结构体成员,都要明确告诉编译器是怎么对齐的哈

出0入0汤圆

发表于 2017-7-19 09:55:22 | 显示全部楼层
牛逼



出0入0汤圆

发表于 2017-7-19 10:37:37 | 显示全部楼层
位域这个东西能不用就不要用了。除了看起来高大上,没有啥用。

出0入0汤圆

 楼主| 发表于 2017-7-19 10:42:54 | 显示全部楼层
728196 发表于 2017-7-19 10:37
位域这个东西能不用就不要用了。除了看起来高大上,没有啥用。

兄台何出此言,还请指教下

出0入0汤圆

发表于 2017-7-19 12:41:49 | 显示全部楼层
728196 发表于 2017-7-19 10:37
位域这个东西能不用就不要用了。除了看起来高大上,没有啥用。

虽然出错几率大,但位域确实符合人类思维模式,清晰明了,比用或与实现置位与清位出错的概率小点。

出870入263汤圆

发表于 2017-7-20 13:20:58 | 显示全部楼层
snoopyzz 发表于 2017-7-18 15:56
楼主你自己用了union!!

自然是共用了, union里每个成员都是共用的, 你这样定义后BITbit01和BIT01是完全等 ...


你别急,好好再去了解一下结构体位域的概念。
楼主的理解没有错,说明他学得比你扎实。

出0入0汤圆

发表于 2017-7-20 13:28:38 | 显示全部楼层
armstrong 发表于 2017-7-20 13:20
你别急,好好再去了解一下结构体位域的概念。
楼主的理解没有错,说明他学得比你扎实。 ...

我没看清LZ的程序, 看成第二次赋值也是赋值的CHAR[0]

出870入263汤圆

发表于 2017-7-20 13:29:11 | 显示全部楼层
WM_CH 发表于 2017-7-18 15:35
我的意思是说,修改位域那个变量,只会修改CHAR[0]所在的字节中,和位域变量共用的几个bit,
而不应该修 ...

IAR的结果是正确的,如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出870入263汤圆

发表于 2017-7-20 13:35:42 | 显示全部楼层
本帖最后由 armstrong 于 2017-7-20 13:37 编辑

人生苦短,我用IAR
以前很多次程序不如意,都怀疑编译器;可惜每次都证明是我自己的错。
所以我对IAR的信任度是越来越高。MDK的问题我是不愿意去解决了。
MDK可谓是金玉(界面)其外,败絮(编译套件)其中。

出0入0汤圆

发表于 2017-7-20 13:38:35 | 显示全部楼层
C语言的位域功能可移植性很差,不同编译器的结果不一样很正常。
但一般注意好大小端,不用的位全部用空位域占上,用起来还是比较爽的。

出870入263汤圆

发表于 2017-7-20 13:38:40 | 显示全部楼层
xf331785508 发表于 2017-7-19 12:41
虽然出错几率大,但位域确实符合人类思维模式,清晰明了,比用或与实现置位与清位出错的概率小点。 ...

说得对。位域的存在就是为了这个。

出0入0汤圆

 楼主| 发表于 2017-7-20 15:21:38 | 显示全部楼层
armstrong 发表于 2017-7-20 13:35
人生苦短,我用IAR
以前很多次程序不如意,都怀疑编译器;可惜每次都证明是我自己的错。
所以我对IA ...

原来是MDK的锅
不过还是把空位域补上比较好。

出0入0汤圆

发表于 2017-7-20 21:30:39 来自手机 | 显示全部楼层
armstrong 发表于 2017-7-20 13:35
人生苦短,我用IAR
以前很多次程序不如意,都怀疑编译器;可惜每次都证明是我自己的错。
所以我对IA ...

大神给讲讲如何“金玉其外,败絮其中”的?!

出0入0汤圆

发表于 2017-7-20 21:55:01 来自手机 | 显示全部楼层
WM_CH 发表于 2017-7-18 16:37
这里有两个概念比较模糊,
第一个是大小端问题,即BITbit01和CHAR[x]形成联合体,x到底是0还是7
第二个是BI ...

这个,建议自己填充位域,这也是一个好习惯,尤其是你的举例,这个很可能是属于c语言的未定义内容,刚好就出错了

出0入0汤圆

发表于 2017-7-20 21:57:20 来自手机 | 显示全部楼层
怎么感觉是这两个匿名结构体被合并了,难道匿名结构体还有自动合并功能啊

出0入0汤圆

发表于 2017-7-25 10:49:25 | 显示全部楼层
这个问题之前还没遇见过,学习了,以后用位域,把不用的空位域填上,就不用担心编译器的问题了

出0入0汤圆

发表于 2017-7-25 10:53:36 | 显示全部楼层
armstrong 发表于 2017-7-20 13:35
人生苦短,我用IAR
以前很多次程序不如意,都怀疑编译器;可惜每次都证明是我自己的错。
所以我对IA ...

大神,我也想知道MDK的败絮还有那些,严重的话,可以考虑换编译器

出0入0汤圆

发表于 2017-7-25 18:04:46 | 显示全部楼层
结构体位域赋值,学习了,非常喜欢这样的技术讨论帖!

出0入0汤圆

发表于 2017-8-3 09:24:21 | 显示全部楼层
我只能说我看不懂
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-17 20:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表