This topic has been archived. It cannot be replied.
-
工作学习 / 学科技术讨论 / 廉颇老亦, 谁能告诉我结果,并告诉我原因? ( C question)main()
{
int x=20,y=35;
x=y++ + x++;
y= ++y + ++x;
printf(“%d%d\n”,x,y);
}
main()
{
volatile int x=20,y=35;
x=y++ + x++;
y= ++y + ++x;
printf(“%d%dn”,x,y);
}
-eagle_no1(瞎起哄);
2009-7-15
{267}
(#5420989@0)
-
第一个结果是 94 57?第二个不清楚, 忘了volatile是啥意思了。x=y++ + x++ : x=20+35 +1=56, y=36
y=++y + ++x : y=1+36 + 1+56= 94
-walkthrough(胸围>肚围);
2009-7-15
{74}
(#5421055@0)
-
second thought. 93,56x=y++ + x++ : x=20+35 =55, y=35+1=36
y=++y + ++x : y=1+36 + 1+55= 93, x=55+1=56
-walkthrough(胸围>肚围);
2009-7-15
{80}
(#5421077@0)
-
2259
-eagle_no1(瞎起哄);
2009-7-15
(#5421093@0)
-
看来用CACHE跟不用还是有很大区别的嘛。
-luckystar889(luckystar);
2009-7-15
(#5421197@0)
-
volitale的作用好象不是禁Cache而是禁Reg吧?
-philishave(Philishave);
2009-7-15
(#5421263@0)
-
对的; 第二个呢? 牛哥,猫哥,车哥怎么都躲起来了?
-eagle_no1(瞎起哄);
2009-7-15
(#5421085@0)
-
牛人们是不需要做这些的,打发手下的实习生和苦力们去干就可以了。:P
-pipe(Pipe);
2009-7-15
(#5421095@0)
-
是啊,我也觉得我自己不需要做这些,但不做不行啊,你看,关键时候全躲起来了。 :-)
-eagle_no1(瞎起哄);
2009-7-15
(#5421109@0)
-
2. Depends on external change (interrupt service or mapped hardware) in embedded system.
1. I had the 2nd thought, which one is correct or depends on compiler?
-panda5wu(郁闷:天生我才咋没用);
2009-7-15
(#5421231@0)
-
1) is clear, #5421290@0; but i got confussed with the running result with is 2259, i guess something wrong somewhere;
-eagle_no1(瞎起哄);
2009-7-15
(#5421302@0)
-
呵呵,我已经15年没编过代码了,不是干这行的。本科那会儿学的那些基本编程的东西也早忘光了。
-mikesmith(老猫);
2009-7-15
{1735}
(#5421254@0)
-
佩服!站的高度的确不一样!我经常纠缠于具体细节,缺乏outside the box思考问题的习惯。
-wangqingshui(忘情水);
2009-7-15
(#5421358@0)
-
不敢不敢。
-mikesmith(老猫);
2009-7-16
(#5422882@0)
-
这都那跟那啊? 我是偶然看到这页想到 volatile的
-eagle_no1(瞎起哄);
2009-7-15
(#5421396@0)
-
That bug explained the result of 2259.. I guess.. or maybe it is just coincidence
-mikesmith(老猫);
2009-7-15
(#5421463@0)
-
maybe it's the same kind of bug, just wandering how does the compiler deal with those code...
-eagle_no1(瞎起哄);
2009-7-15
(#5421522@0)
-
You can check C89 for official answer. This is about language standard question.
-iwantcar_majia(iwantcar);
2009-7-16
(#5422271@0)
-
volatile 的意思是其值 可被 另一线程 或 硬件 随时改变。如果没有被改变, volatile变量和一般变量应该没有区别
-limn(limn);
2009-7-19
(#5428097@0)
-
第一个不是5693吗?
-wangqingshui(忘情水);
2009-7-15
(#5421205@0)
-
帮我看看我哪里错了吧
-wangqingshui(忘情水);
2009-7-15
{639}
(#5421261@0)
-
seemsstep1: x = y + x; (55)
step2; y = y+1; (36)
step3; x= x+1; (56)
step4: y= y+1; (37)
step5: x=x+1; (57)
step6:y=y+x; (94)
-eagle_no1(瞎起哄);
2009-7-15
{141}
(#5421290@0)
-
FYI: C Language Operator Precedence Chart
-wangqingshui(忘情水);
2009-7-15
(#5421319@0)
-
如果是单线程,纯内存操作,我看不出有volatile 对第二题的影响。能请夏老师指点一下吗?
-wangqingshui(忘情水);
2009-7-15
(#5421222@0)
-
第一个 #5421055@0的解释 和运算结果一致;2259 是第二个的运行结果; 在x86上,linux ,gcc编译运行的; 正抓狂想原因; 可惜x86汇编不熟;
-eagle_no1(瞎起哄);
2009-7-15
(#5421241@0)
-
为什么要声明volatile?是不是被你贴出来的逻辑以外的东东改变了数值?那这里说什么都白搭。
-wangqingshui(忘情水);
2009-7-15
(#5421267@0)
-
completed code:#include "stdio.h"
void func()
{
volatile int x=20, y=35;
x=y++ + x++;
y= ++y + ++x;
printf("%d%d\n",x,y);
}
main()
{
func();
}
-eagle_no1(瞎起哄);
2009-7-15
{155}
(#5421314@0)
-
I usually do not pay too much attention to complicated syntax skills, like macros, unless I have no choice. Here what concerns me most is the intention of declaring "volatile", if the 2 variables are not used by other threads or external devices.
-wangqingshui(忘情水);
2009-7-15
(#5421333@0)
-
夏老弟,看汇编没用,找一本最新的C标准,好好读读operator precedence一节。俺现在太忙了,等下下星期闲下来,再给出标准答案。
-hubeir(作曲家wannabe);
2009-7-16
{48}
(#5421631@0)
-
hehe, here is the result #5422795@0
-eagle_no1(瞎起哄);
2009-7-16
(#5423894@0)
-
"如果是单线程,纯内存操作,我看不出有volatile 对第二题的影响" --- 能解释一下如果是多线程环境又会怎样?
-nicetomeetyou(蓦然回首彩虹跨天地);
2009-7-16
(#5421794@0)
-
这个volatile就是告诉编译器,不要作任何优化,每次操作老老实实从内存把数值load到寄存器,避免多线程(中断 )间失步错误;
-eagle_no1(瞎起哄);
2009-7-16
(#5421863@0)
-
谢谢,好久不用c, and embedded system, 脑子都简单了. 这可能是个有所帮助的link.
-nicetomeetyou(蓦然回首彩虹跨天地);
2009-7-16
(#5421904@0)
-
volatile variable:
-qwertyasd(东北人);
2009-7-16
{536}
(#5421869@0)
-
humm. so my naive question is: If a variable is declared as volatile, all codes related with this variable will not be optimized by compiler, or, compiler simply shut off its optimization for all codes?
-nicetomeetyou(蓦然回首彩虹跨天地);
2009-7-16
(#5421930@0)
-
I don't know the compiler's behavior on this case. But I guess a goos compiler should optimize other parts of code that are not related to the volatile variables base on the options from the user.
-qwertyasd(东北人);
2009-7-16
(#5421999@0)
-
Compiler dependant吧?俺估计得objdump后才能告诉你结果。不过出这种题目是吃饱了撑的。招人考这种题目还不如问人DMA要注意些啥来得实际。
-philishave(Philishave);
2009-7-15
(#5421233@0)
-
高人来了; (不是考题,正好遇到了)
-eagle_no1(瞎起哄);
2009-7-15
{1867}
(#5421258@0)
-
X86好长一段时间没工作过了。不是很熟。Coldfire及ARM反倒好一点。俺的意思是有些东西是C spec里没硬性规定一定要怎样的。所以不同的Compiler会有不同的编译方试,从而导致结果的不同。印象中volatile也是如此,C spec里也印象中volatile也是如此,C spec里也没说Compiler一定不能把它优化到Reg,Compiler仍可忽略volatile.另外你objdump还可以多dump一些东西出来吧。
-philishave(Philishave);
2009-7-15
{135}
(#5421458@0)
-
我是偶然遇到这个结果, 估计象猫哥蒙的---是compiler的bug, 象是相加的结果没有load到内存,可惜不会用汇编求证; 。。。 objdump 可以dump很多, 我特意写成func,好objdump分离问题;
-eagle_no1(瞎起哄);
2009-7-15
(#5421549@0)
-
objdump of second main. gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291] GNU objdump (GNU Binutils; openSUSE 11.1) 2.19
-qwertyasd(东北人);
2009-7-16
{15929}
(#5421861@0)
-
翻译成c是这样子的
-baalinca(三碗不过冈十点不上网);
2009-7-17
{1515}
(#5425373@0)
-
对呀! 高人啊。和我蒙的是一致的 :-) #5422795@0 and #5423300@0
-eagle_no1(瞎起哄);
2009-7-17
(#5425591@0)
-
都很努力学习嘛, 夜校啊?
-iceblake(美丽之夏,CYCLING);
2009-7-15
(#5421372@0)
-
夏老师的贴,一定要捧场的。
-wangqingshui(忘情水);
2009-7-15
(#5421382@0)
-
都是能人, 佩服佩服
-iceblake(美丽之夏,CYCLING);
2009-7-15
(#5421400@0)
-
我现在准备混在事业版和牛哥,猫哥,车哥,忘情水哥学习了; :-)
-eagle_no1(瞎起哄);
2009-7-15
(#5421434@0)
-
哈哈,把我与事业版的大腕列在一对了,荣幸!谢谢夏老师提携!
-wangqingshui(忘情水);
2009-7-15
(#5421451@0)
-
都挺能起哄. 我能在这里当学生嘛?
-iceblake(美丽之夏,CYCLING);
2009-7-15
(#5421466@0)
-
当冰哥。在这里没有客气的。
-mikesmith(老猫);
2009-7-15
(#5421509@0)
-
冰歌,好听些
-iceblake(美丽之夏,CYCLING);
2009-7-15
(#5421516@0)
-
bingo
-wangqingshui(忘情水);
2009-7-15
(#5421530@0)
-
对了,我原来的大号就叫哄哥,应是被你们整成了什么“夏老师”
-eagle_no1(瞎起哄);
2009-7-15
(#5421442@0)
-
多谢,多谢; 回头再发一帖,多多帮忙;
-eagle_no1(瞎起哄);
2009-7-15
(#5421425@0)
-
我看了这贴不回不行。编程的要领是什么?3R(自己Google去)。可读性是非常重要的。我编写了22年程序,重来都以可读性为上,这样其他人也好跟进你的程序。若我看到其他人写出搂主题目这样含糊不清故弄玄虚的程序,我立马叫他重编,若他不重编,立马赶人。
-armstrong2(动动猴他爸);
2009-7-15
(#5421452@0)
-
同感。不是干活是玩人呢。
-w4b(Watch for Beauty);
2009-7-15
(#5421477@0)
-
痛感.
-iceblake(美丽之夏,CYCLING);
2009-7-15
(#5421517@0)
-
谔谔锷,这词可不能瞎说,痛并快乐着
-w4b(Watch for Beauty);
2009-7-15
(#5421564@0)
-
+1. LZ在逗着玩呢
-wangqingshui(忘情水);
2009-7-15
(#5421523@0)
-
哎! 又来一个当领导的; 怎么都不喜欢具体分析问题解决问题呢?
-eagle_no1(瞎起哄);
2009-7-15
(#5421531@0)
-
华人小公司的技术骨干?谁要是不听你的,立马赶人?这就是贵公司的企业文化?这种公司,不用赶,有点本事的都不会在那里混。有你这样的小头头,算你那些同事倒霉。
-hubeir(作曲家wannabe);
2009-7-17
(#5426311@0)
-
换个角度说,虽然不推荐代码写成这样,但是你最好能看懂,所以俺们这里讨论讨论是必要的 - 当然,这是理论上说。实际上,我还没见过哪个real project中出现过类似的代码,程序员们还是有点common sense的。。。一般会让它易读一点,因为他们也不想自己日后费脑子。。。
-erixfan(erixfan);
2009-7-24
(#5440293@0)
-
俺以务实的精神讲,答案是57,94和56,93。AIX Polymake下 编译并执行。
-laura999(Laura);
2009-7-16
(#5422699@0)
-
fair enough
-eagle_no1(瞎起哄);
2009-7-16
(#5422711@0)
-
Actually the root cause is x= y++ + x++, which behavior according to c standard is undefined, so it just happens to be the output you expect in case of without volatile keyword.
-vacu(vacu);
2009-7-16
{20}
(#5422758@0)
-
good to know. thx
-eagle_no1(瞎起哄);
2009-7-18
(#5426780@0)
-
without the volatile, though the x = y++ + x++ could be handled differenly by different compiler, but the results are same.
-frankwoo(柳五随风);
2009-9-19
(#5558418@0)
-
why is 2259?
-eagle_no1(瞎起哄);
2009-7-16
{2454}
(#5422795@0)
-
"google一把,就蒙对了答案".. LOL..不会编程,还是会google的。
-mikesmith(老猫);
2009-7-16
(#5422879@0)
-
lea (%edx,%ecx,1),%eax = ecx * 1 + edx -> eax.
-canadiantire(轮胎 - Cornelius);
2009-7-16
(#5423213@0)
-
ok. thx; this addresses my confusion here. compiler should load the X value into register again before do X++, which is exactly volatile supposed to do.
-eagle_no1(瞎起哄);
2009-7-16
(#5423300@0)
-
刚才在Cygwin的gcc上面试了一下, 发现gcc还是牛多了,hehe
-canadiantire(轮胎 - Cornelius);
2009-7-16
(#5423528@0)
-
结果是什么呀?
-eagle_no1(瞎起哄);
2009-7-16
(#5423588@0)
-
5693
-canadiantire(轮胎 - Cornelius);
2009-7-17
(#5424220@0)
-
比较搞的是我把你的第一个func放上去想比较一下生成的汇编有啥区别, 结果被gcc优化成这个样子:pushl %ebp
movl $94, %edx
movl %esp, %ebp
movl $57, %eax
subl $24, %esp
movl %edx, 8(%esp)
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
leave
ret
-canadiantire(轮胎 - Cornelius);
2009-7-17
{170}
(#5424237@0)
-
真是有钱有闲又有权啊.我实在没有精力研究这个问题.C还没有认全.
-iwantcar_majia(iwantcar);
2009-7-18
(#5426969@0)
-
好象没有标准答案,不同编译器有不同的实现(没查C标准,不十分肯定)。俺的理解,下面两个答案都应该是正确的:Without volatile:
int x = 20, y = 35;
x = y + x;
x++;
y++;
++y;
++x;
y = y + x;
Results are (57, 94)
Or
int x = 20, y = 35;
register A = y + x;
x++; // this increment will be discarded later
y++;
x = register A; // x <-- 55
++y;
++x;
y = y + x;
Results are (56, 93)
-hubeir(作曲家wannabe);
2009-7-17
{295}
(#5424068@0)
-
加上volatile 限定词之后,又多了一种可能:volatile int x = 20;
volatile int y = 35;
reg X <-- x;
reg Y <-- y;
reg Z = reg Y + reg X;
x <-- reg Z;
reg X++;
reg Y++;
x <-- reg X; // the writeback happens because x is volatile. x == 21 here !
y <-- reg Y;
问题的关键在 x = y++ + x++; 一句,x赋值在先,还是加1在先,C标准有明确的规定吗?
-hubeir(作曲家wannabe);
2009-7-17
{303}
(#5424076@0)
-
no, 5693 should bex=x+y
y++
x++
y=x+y
x++
y++
this increment can not be discarded later, it's compiler error again otherwise;
-eagle_no1(瞎起哄);
2009-7-17
{116}
(#5424444@0)
-
按照操作符优先权来解释这段程序,只有一个答案,5794,没有歧义。得出不同结果的编译器有bug,至少是没有严格遵守C标准。
-baalinca(三碗不过冈十点不上网);
2009-7-17
(#5425488@0)
-
参考答案看了大家的回复,我作为半个电脑工程师,不知道该跟大家说什么好。先公布一下参考答案。
本答案是手算结果,大家可以用电脑校验一下。
build without -O:
both are the same results as:x=57. y=94.
build with -O2 or -O2:
seconds result is: x=57. y=94.
first result is: x=22 y=59
本人今年年底将失业。如果大家有工作,介绍一下。
-goodlifeseek(chineseman);
2009-7-25
{323}
(#5442265@0)
-
上面讨论很充分了,编译器相关, x=22 y=59的结果应该是编译器的bug造成的。
-eagle_no1(瞎起哄);
2009-7-25
(#5442284@0)
-
年底还早着呢,找新工作应该没问题的; :-)
-eagle_no1(瞎起哄);
2009-7-25
(#5442289@0)
-
volatile + x=x + optimization 真可怕
-frankwoo(柳五随风);
2009-9-18
(#5558409@0)
-
我来回答这个问题:在C(或者C++)语言的标准里,有一个概念称为sequence point,请进来看……
-perryuan(perryuan);
2009-10-25
{2081}
(#5633086@0)