且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C++条件运算符的运算问题,求指教

更新时间:2022-10-15 17:55:43

前言

每次遇见问c++问题的,都是这样的比较基础的问题,这段话我每次都说:
反汇编是c++程序员必掌握的一项技能!!!
反汇编是c++程序员必掌握的一项技能!!!
反汇编是c++程序员必掌握的一项技能!!!
否则,在调试程序的时候就跟瞎子没什么两样,只能靠猜。

分析

实际上根据经验我认为远没有那么复杂,更不是未定义行为,而是运算符作用域的问题。
这个表达式正确的执行顺序如下:

if(1){
    ++x;//这句没有用,在release模式下会被编译器优化掉
    ++y;//y+1
}else{
    --x;
}
--y;//y-1
cout<<y<<endl;

一目了然,因为 :运算符的优先级要高于,。而:之前的条件为真,只能顺序执行,而之后的,则超出的:运算符作用域。所以,无论条件成立与否,--y一定会被执行。
所以正确写法应该加括号.

auto y=someValue ? (++x, ++y) : (--x, --y);
//y=6

反汇编

00F0625E  mov         dword ptr [someValue],1  
00F06265  mov         dword ptr [x],1  
00F0626C  mov         dword ptr [y],5  
00F06273  cmp         dword ptr [someValue],0  
00F06277  je          main+56h (0F06296h)  ;判断条件是否成立
00F06279  mov         eax,dword ptr [x]  
00F0627C  add         eax,1  
00F0627F  mov         dword ptr [x],eax  
00F06282  mov         ecx,dword ptr [y]  
00F06285  add         ecx,1  ;y的值+1变成了6
00F06288  mov         dword ptr [y],ecx  
00F0628B  mov         edx,dword ptr [y]  
00F0628E  mov         dword ptr [ebp-0E8h],edx
00F062A8  mov         edx,dword ptr [y]  
00F062AB  sub         edx,1  ;再减一变成5
00F062AE  mov         dword ptr [y],edx ;传值返回