any_014 发表于 2012-3-5 12:37:04

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)。

liurangzhou 发表于 2012-3-5 13:08:22

补补C吧,不知道你是要它加还是不要它加,按理是不加

any_014 发表于 2012-3-5 13:13:41

回复【1楼】liurangzhou
-----------------------------------------------------------------------

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

babysnail 发表于 2012-3-5 13:14:10

回复【1楼】liurangzhou
-----------------------------------------------------------------------

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

vivalite 发表于 2012-3-5 13:26:43

selkey1f += selkey1f;

selkey1f++;

any_014 发表于 2012-3-5 13:30:22

回复【3楼】babysnail蜗仔
-----------------------------------------------------------------------

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

any_014 发表于 2012-3-5 13:33:34

回复【4楼】vivalite
-----------------------------------------------------------------------

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

chinaye1 发表于 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++;

babysnail 发表于 2012-3-5 13:37:34

这是标准答案:

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

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

ddg_int 发表于 2012-3-5 13:40:33

回复【7楼】chinaye1程序猿
-----------------------------------------------------------------------

同意

takashiki 发表于 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对消除歧义提高程序的鲁棒性确实非常有用。

any_014 发表于 2012-3-5 13:44:50

回复【7楼】chinaye1程序猿
-----------------------------------------------------------------------
确实,selkey1f= ++selkey1f;行。
那么,既然selkey1f=selkey1f++;可表述成
1、selkey1f=selkey1f;
2、selkey1f++;
那最后selkey1f不是应该加一了吗?

any_014 发表于 2012-3-5 13:48:36

回复【10楼】takashiki岚月影
-----------------------------------------------------------------------

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

babysnail 发表于 2012-3-5 22:52:26

回复【11楼】any_014
-----------------------------------------------------------------------
那最后selkey1f不是应该加一了吗?
-----------------------------------------------------------------------

我理解应该是这样的

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

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

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

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

millwood0 发表于 2012-3-6 07:10:38

"y=y++;"

think of it as the following:

y=y;
y++;

hope it helps.

snoopyzz 发表于 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, ++只是徒劳

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

pengshipower 发表于 2012-3-6 09:49:54

回复【10楼】takashiki 岚月影
-----------------------------------------------------------------------

eduhf_123 发表于 2012-3-6 11:02:06

编译器并没有错。

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

avrstm32 发表于 2012-3-6 11:16:08

回复【4楼】vivalite
-----------------------------------------------------------------------

selkey1f += selkey1f; ???

automaticdai 发表于 2012-3-6 11:19:00

这样的语句确实歧义性较大。
应该尽量少使用。

avrstm32 发表于 2012-3-6 11:27:13

应该是加了1的,楼主跳开一条语句再检查selkey1f的值,是否有变化。i++; 是先使用后加,编译器保证在本语句执行完毕!!!!!!!,下一条语句执行前加1的。

any_014 发表于 2012-3-6 11:35:54

TO 20L,结果确实没加一。
TO 17L,从编译的汇编结果看,确实是这样子的。你说的优化等级在哪里设置?

avrstm32 发表于 2012-3-6 11:42:54

回复【21楼】any_014
-----------------------------------------------------------------------

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

zajia 发表于 2012-3-6 11:47:13

我经常搞不懂, 所以这种情况下 加()

any_014 发表于 2012-3-6 12:31:31

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)

avrstm32 发表于 2012-3-6 13:31:37

回复【24楼】any_014
---------------------------------------------------------------------
看看优化等级。如果还不行,就只有不采用Y=Y++;这种表达方式了。

eduhf_123 发表于 2012-3-6 13:48:30

回复【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)

i7gly 发表于 2012-3-8 02:53:39

我个人觉得这样有歧义的程序尽量避免或者加括号,毕竟编译器是死的,不可能跟上人的思想……

lusson 发表于 2012-3-9 09:20:03

我很奇怪楼主怎么想的。。
为什么会写出这样的语句
想加1直接就
i++
或者 i = i+1
或者 I += 1
为什么非要在这个问题上纠结,写一个简单明了的语句是有多么的重要啊

Alimy 发表于 2012-3-9 09:23:01

y=y++;
搞不懂楼主到底想做什么?
页: [1]
查看完整版本: KEIL编译出错?关于y=y++;