Pavel said:
No, the non-short-circuiting operator doesn't check the vale of a before
doing the operattion.
This code:
a &= b;
compiles into:
movzx eax, byte ptr [rsp+20h]
movzx ecx, bytr ptr [rps+21h]
and eax, ecx
mov byte ptr [rsp+20h], al
I was assuming that "a" and "b" are placeholders for arbitrary
expressions, not just variables. I see that it used the AND operator
here - but I doubt whether it will do the same in e.g. a statement
such as:
Yes, it does it the same way. There is more code to get the location of
foo.Bar.Baz and to evaluate the expression x > y, but the code for the
&= operation is still an and operation:
; get foo.Bar
mov rax,qword ptr [rsp+30h]
cmp byte ptr [rax],0
mov rcx,qword ptr [rsp+30h]
call FFFFFFFFFFEC96D0
mov qword ptr [rsp+40h],rax
; get Baz
mov rax,qword ptr [rsp+40h]
movzx edx,byte ptr [rax+8]
; evaluate x > y
xor ecx,ecx
mov eax,dword ptr [rsp+28h]
cmp dword ptr [rsp+24h],eax
setg cl
mov dword ptr [rsp+48h],ecx
; &=
mov ecx,edx
and ecx,dword ptr [rsp+48h]
; set Baz
mov rax,qword ptr [rsp+40h]
mov byte ptr [rax+8],cl
I'd rather expect it to stick to conditional jumps here (since it'll
have to do CMP either way, might as well jump right then, instead of
doing SET/AND).
Nope, no jumps.
By the way, the above disassembly is from the x64 JIT, right? Have you
tried it on x86? the difference between implementations can be very
drastic at times.
Good point. Yes, it was x64 code. The x86 code looks like this:
mov eax, dword ptr [ebp-28h]
and eax, dword ptr [ebp-2Ch]
and eax, 0ffh
mov dword ptr [ebp-28h]
It reads and writes the bool values as dwords instead of bytes, but
other than that it's pretty much the same.