KEIL编译出错?关于y=y++;
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)。 补补C吧,不知道你是要它加还是不要它加,按理是不加 回复【1楼】liurangzhou
-----------------------------------------------------------------------
要它加,不理解你说的“按理是不加”。能解释下吗? 回复【1楼】liurangzhou
-----------------------------------------------------------------------
幽默 +1。lz复习一下优先级 selkey1f += selkey1f;
或
selkey1f++; 回复【3楼】babysnail蜗仔
-----------------------------------------------------------------------
++优先级高于赋值运算符,但我觉得应该还是加一。 回复【4楼】vivalite
-----------------------------------------------------------------------
selkey1f++;
或selkey1f+=1;都没问题。
但写成selkey1f=selkey1f++;就不行。 回复【6楼】any_014
回复【4楼】vivalite
-----------------------------------------------------------------------
selkey1f++;
或selkey1f+=1;都没问题。
但写成selkey1f=selkey1f++;就不行。
-----------------------------------------------------------------------
selkey1f= ++selkey1f;行
写成selkey1f=selkey1f++;这样是表示
1、selkey1f=selkey1f;
2、selkey1f++; 这是标准答案:
++i,--i 在前 是先加(减)后使用
i++,i--在后则是先使用后加(减) 回复【7楼】chinaye1程序猿
-----------------------------------------------------------------------
同意 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对消除歧义提高程序的鲁棒性确实非常有用。 回复【7楼】chinaye1程序猿
-----------------------------------------------------------------------
确实,selkey1f= ++selkey1f;行。
那么,既然selkey1f=selkey1f++;可表述成
1、selkey1f=selkey1f;
2、selkey1f++;
那最后selkey1f不是应该加一了吗? 回复【10楼】takashiki岚月影
-----------------------------------------------------------------------
受教了,谢谢。也谢谢楼上的各位。 回复【11楼】any_014
-----------------------------------------------------------------------
那最后selkey1f不是应该加一了吗?
-----------------------------------------------------------------------
我理解应该是这样的
1、取=号右边即 《selkey1f++》表达式的值 ,根据
++i,--i 在前 是先加(减)后使用
i++,i--在后则是先使用后加(减)值是其本身,即汇编中的R7
2、按优先级关系 selkey1f++ 先执行
3、才是赋值运算 selkey1f= 第1步取的值,即汇编中的R7 "y=y++;"
think of it as the following:
y=y;
y++;
hope it helps. 回复【14楼】millwood0
"y=y++;"
think of it as the following:
y=y;
y++;
hope it helps.
-----------------------------------------------------------------------
这样理解是错的,等号右边运算是优先于左边的,但y++是先取值,再++
利用中间寄存器赋值的编译器会这样处理,
reg=y;
y++;
y=reg;
最后结果仍是之前的y, ++只是徒劳
但是优化等级高了,结果就可能会不一样了 回复【10楼】takashiki 岚月影
-----------------------------------------------------------------------
顶 编译器并没有错。
LZ不妨把selkey1f声明成volatile的,然后分别在不同环境下重新编译,来看看结果。 回复【4楼】vivalite
-----------------------------------------------------------------------
selkey1f += selkey1f; ??? 这样的语句确实歧义性较大。
应该尽量少使用。 应该是加了1的,楼主跳开一条语句再检查selkey1f的值,是否有变化。i++; 是先使用后加,编译器保证在本语句执行完毕!!!!!!!,下一条语句执行前加1的。 TO 20L,结果确实没加一。
TO 17L,从编译的汇编结果看,确实是这样子的。你说的优化等级在哪里设置? 回复【21楼】any_014
-----------------------------------------------------------------------
从汇编上看,确实没有加1,你把selkey1f声明成volatile试试,应该就可以了。 我经常搞不懂, 所以这种情况下 加() TO 17L,22L
http://cache.amobbs.com/bbs_upload782111/files_53/ourdev_724444AKK3S5.jpg
(原文件名:未命名.jpg)
是这样定义吗?
结果仍是:
http://cache.amobbs.com/bbs_upload782111/files_53/ourdev_724445RIGM92.jpg
(原文件名:QQ截图20120306123146.jpg) 回复【24楼】any_014
---------------------------------------------------------------------
看看优化等级。如果还不行,就只有不采用Y=Y++;这种表达方式了。 回复【24楼】any_014
-----------------------------------------------------------------------
这是我试验的结果:
http://cache.amobbs.com/bbs_upload782111/files_53/ourdev_724458L6YCGK.png
(原文件名:20120306134449.png)
编译器信息:
http://cache.amobbs.com/bbs_upload782111/files_53/ourdev_724459TQMSC6.png
(原文件名:20120306134747.png) 我个人觉得这样有歧义的程序尽量避免或者加括号,毕竟编译器是死的,不可能跟上人的思想…… 我很奇怪楼主怎么想的。。
为什么会写出这样的语句
想加1直接就
i++
或者 i = i+1
或者 I += 1
为什么非要在这个问题上纠结,写一个简单明了的语句是有多么的重要啊 y=y++;
搞不懂楼主到底想做什么?
页:
[1]