2017-07-02 57 views
2

我一直认为^ = B^= A^= B掉期< - > B.我猜测,这条线应评估有权在3个步骤即可:A^= B^= A^= B;出人意料的结果在C#中的Visual Studio

1) A ^= B; 
2) B ^= A; 
3) A ^= B; 

但是不知怎的,在C#中,如果你在一行中完成,它就变为0。我查看了程序集,发现原来的A被存储在第一步,为什么在最后的第三步,而不是采取A的实际当前值,代码使用缓存的原始值。大会是这样的:

mov   eax,dword ptr [ebp-40h] //eax <- A 
mov   dword ptr [ebp-7Ch],eax //C <- A (why cache?) 
mov   eax,dword ptr [ebp-44h] //eax <- B 
xor   dword ptr [ebp-40h],eax //A ^= B 
mov   eax,dword ptr [ebp-40h] //eax <- A 
xor   dword ptr [ebp-44h],eax //B ^= A 
mov   eax,dword ptr [ebp-7Ch] //eax <- C (?) 
xor   eax,dword ptr [ebp-44h] //eax ^= B (= C^B) 
mov   dword ptr [ebp-40h],eax //A = C^B (instead of A^B) 

似乎在C OK ++和汇编只使用2个变量:

mov   eax,dword ptr [a] 
xor   eax,dword ptr [b] 
mov   dword ptr [a],eax 
mov   ecx,dword ptr [b] 
xor   ecx,dword ptr [a] 
mov   dword ptr [b],ecx 
mov   edx,dword ptr [a] 
xor   edx,dword ptr [b] 
mov   dword ptr [a],edx 

我缺少的东西?

+0

说不上C#,但可能涉及:https://stackoverflow.com/q/38421671/3002139 –

+0

出于好奇:是否有该代码实际应用? – MikeMB

+0

https://stackoverflow.com/q/5577140 – AlexD

回答

2

在C++中,这将是一个未定义的行为*,因为多重无序分配。

在C#中,这是完全有效的,并且零是正确的结果。

要知道为什么认为XOR荷兰国际集团任意数量的本身让步零,因为在位模式每项运动也有相同的位。而且,异或顺序并不重要。这就是为什么B以A的旧值结束,而A最终为零。

* C++之前17,反正。

+0

是的,谢谢大家。我搜索得很糟糕。问题已经得到解答。对不起 – Empted

+0

在C++ 17中改变了分配的顺序规则,所以请谨慎对待您的声明。 – Yakk

相关问题