搜索
bottom↓
回复: 29

KEIL编译出错?关于y=y++;

[复制链接]

出0入0汤圆

发表于 2012-3-5 12:37:04 | 显示全部楼层 |阅读模式
850:           selkey1f=selkey1f++;
   851:     
C:0x03D3    AF12     MOV      R7,selkey1f(0x12)
C:0x03D5    0512     INC      selkey1f(0x12)
C:0x03D7    8F12     MOV      selkey1f(0x12),R7

在自己的机子上编译的,结果selkey1f不变化;用的kel4,而在同事的机子上keil2及keil4均编译为 INC selkey1f(0x12)。

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-3-5 13:08:22 | 显示全部楼层
补补C吧,不知道你是要它加还是不要它加,按理是不加

出0入0汤圆

 楼主| 发表于 2012-3-5 13:13:41 | 显示全部楼层
回复【1楼】liurangzhou  
-----------------------------------------------------------------------

要它加,不理解你说的“按理是不加”。能解释下吗?

出0入0汤圆

发表于 2012-3-5 13:14:10 | 显示全部楼层
回复【1楼】liurangzhou  
-----------------------------------------------------------------------

幽默 +1。  lz复习一下优先级

出0入0汤圆

发表于 2012-3-5 13:26:43 | 显示全部楼层
selkey1f += selkey1f;

selkey1f++;

出0入0汤圆

 楼主| 发表于 2012-3-5 13:30:22 | 显示全部楼层
回复【3楼】babysnail  蜗仔
-----------------------------------------------------------------------

++优先级高于赋值运算符,但我觉得应该还是加一。

出0入0汤圆

 楼主| 发表于 2012-3-5 13:33:34 | 显示全部楼层
回复【4楼】vivalite  
-----------------------------------------------------------------------

selkey1f++;
或selkey1f+=1;都没问题。
但写成selkey1f=selkey1f++;就不行。

出0入0汤圆

发表于 2012-3-5 13:36:16 | 显示全部楼层
回复【6楼】any_014  
回复【4楼】vivalite  
-----------------------------------------------------------------------
selkey1f++;
或selkey1f+=1;都没问题。
但写成selkey1f=selkey1f++;就不行。
-----------------------------------------------------------------------

selkey1f= ++selkey1f;行



写成selkey1f=selkey1f++;这样是表示

1、selkey1f=selkey1f;
2、selkey1f++;

出0入0汤圆

发表于 2012-3-5 13:37:34 | 显示全部楼层
这是标准答案:

++i,--i   在前 是先加(减)后使用

i++,i--  在后则是先使用后加(减)

出0入0汤圆

发表于 2012-3-5 13:40:33 | 显示全部楼层
回复【7楼】chinaye1  程序猿
-----------------------------------------------------------------------

同意

出0入93汤圆

发表于 2012-3-5 13:43:35 | 显示全部楼层
selkey1f=selkey1f++;  

这句是有问题的,这里selkey1f被访问(改变)了三次:读,赋值,自增
C语言可不保证这个结果的正确性,因为它违反了关于C语言副作用的描述,至少违反了MISRA C中的三条:
规则 12.1(建议): 不要过分依赖C表达式中的运算符优先规则
规则 12.2(强制): 表达式的值在标准所允许的任何运算次序下都应该是相同的。
规则 12.13(建议): 在一个表达式中,自增(++)和自减(- -)运算符不应同其他运算符混合在一起。

selkey1f=selkey1f++; 的一般行为如下:
C/C++:结果会自增。由于C语言的歧义性极强,结果是不被保证的。
C#/Java:结果不变

另外,你可以说MISRA C变态,找自虐,但是,MISRA C对消除歧义提高程序的鲁棒性确实非常有用。

出0入0汤圆

 楼主| 发表于 2012-3-5 13:44:50 | 显示全部楼层
回复【7楼】chinaye1  程序猿
-----------------------------------------------------------------------
确实,selkey1f= ++selkey1f;行。
那么,既然selkey1f=selkey1f++;可表述成
1、selkey1f=selkey1f;
2、selkey1f++;
那最后selkey1f不是应该加一了吗?

出0入0汤圆

 楼主| 发表于 2012-3-5 13:48:36 | 显示全部楼层
回复【10楼】takashiki  岚月影
-----------------------------------------------------------------------

受教了,谢谢。也谢谢楼上的各位。

出0入0汤圆

发表于 2012-3-5 22:52:26 | 显示全部楼层
回复【11楼】any_014  
-----------------------------------------------------------------------
那最后selkey1f不是应该加一了吗?
-----------------------------------------------------------------------

我理解应该是这样的

1、取=号右边即 《selkey1f++》表达式的值 ,根据

++i,--i   在前 是先加(减)后使用
i++,i--  在后则是先使用后加(减)  值是其本身,即汇编中的R7

2、按优先级关系 selkey1f++ 先执行

3、才是赋值运算 selkey1f= 第1步取的值,即汇编中的R7

出0入0汤圆

发表于 2012-3-6 07:10:38 | 显示全部楼层
"y=y++;"

think of it as the following:

y=y;
y++;

hope it helps.

出0入0汤圆

发表于 2012-3-6 09:40:38 | 显示全部楼层
回复【14楼】millwood0  
"y=y++;"
think of it as the following:
y=y;
y++;
hope it helps.

-----------------------------------------------------------------------
这样理解是错的,等号右边运算是优先于左边的,但y++是先取值,再++

利用中间寄存器赋值的编译器会这样处理,
reg=y;
y++;
y=reg;

最后结果仍是之前的y, ++只是徒劳

但是优化等级高了,结果就可能会不一样了

出0入0汤圆

发表于 2012-3-6 09:49:54 | 显示全部楼层
回复【10楼】takashiki 岚月影
-----------------------------------------------------------------------

出0入0汤圆

发表于 2012-3-6 11:02:06 | 显示全部楼层
编译器并没有错。

LZ不妨把selkey1f声明成volatile的,然后分别在不同环境下重新编译,来看看结果。

出0入0汤圆

发表于 2012-3-6 11:16:08 | 显示全部楼层
回复【4楼】vivalite
-----------------------------------------------------------------------

selkey1f += selkey1f; ???

出0入0汤圆

发表于 2012-3-6 11:19:00 | 显示全部楼层
这样的语句确实歧义性较大。
应该尽量少使用。

出0入0汤圆

发表于 2012-3-6 11:27:13 | 显示全部楼层
应该是加了1的,楼主跳开一条语句再检查selkey1f的值,是否有变化。i++; 是先使用后加,编译器保证在本语句执行完毕!!!!!!!,下一条语句执行前加1的。

出0入0汤圆

 楼主| 发表于 2012-3-6 11:35:54 | 显示全部楼层
TO 20L,结果确实没加一。
TO 17L,从编译的汇编结果看,确实是这样子的。你说的优化等级在哪里设置?

出0入0汤圆

发表于 2012-3-6 11:42:54 | 显示全部楼层
回复【21楼】any_014
-----------------------------------------------------------------------

从汇编上看,确实没有加1,你把selkey1f声明成volatile试试,应该就可以了。

出0入0汤圆

发表于 2012-3-6 11:47:13 | 显示全部楼层
我经常搞不懂, 所以这种情况下 加()

出0入0汤圆

 楼主| 发表于 2012-3-6 12:31:31 | 显示全部楼层
TO 17L,22L

(原文件名:未命名.jpg)
是这样定义吗?
结果仍是:

(原文件名:QQ截图20120306123146.jpg)

出0入0汤圆

发表于 2012-3-6 13:31:37 | 显示全部楼层
回复【24楼】any_014
---------------------------------------------------------------------
看看优化等级。如果还不行,就只有不采用Y=Y++;这种表达方式了。

出0入0汤圆

发表于 2012-3-6 13:48:30 | 显示全部楼层
回复【24楼】any_014  
-----------------------------------------------------------------------

这是我试验的结果:

(原文件名:20120306134449.png)

编译器信息:

(原文件名:20120306134747.png)

出0入0汤圆

发表于 2012-3-8 02:53:39 | 显示全部楼层
我个人觉得这样有歧义的程序尽量避免或者加括号,毕竟编译器是死的,不可能跟上人的思想……

出0入54汤圆

发表于 2012-3-9 09:20:03 | 显示全部楼层
我很奇怪楼主怎么想的。。
为什么会写出这样的语句
想加1直接就
i++
或者 i = i+1
或者 I += 1
为什么非要在这个问题上纠结,写一个简单明了的语句是有多么的重要啊

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-24 02:29

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

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