A ^= B ^= A ^= B;C# Visual Studio 中的意外结果
A ^= B ^= A ^= B; unexpected result in c# visual studio
我一直认为 A ^= B ^=A ^= B 交换 A <-> B。我猜这条线应该分 3 个步骤从右到左评估:
1) A ^= B;
2) B ^= A;
3) A ^= B;
但是在 C# 中,如果你在一行中这样做,A 会变成 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++似乎还可以,程序集仅使用 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
我错过了什么吗?
在C++中,由于多个未排序的赋值,这将是一个未定义的行为*。
在 C# 中,这是完全有效的,零是正确的结果。
要了解为什么考虑将任何数字与自身进行异或运算都会产生零,因为在位模式中的每个运动中都有相等的位。此外,异或顺序并不重要。这就是为什么 B 最终得到 A 的旧值,而 A 最终为零。
*无论如何,在 C++ 17 之前。
相关文章:
- 尝试将字符串/字符转换为整数会产生意外结果
- RapidXML - 代码创建意外结果
- 类中静态函数C++意外结果
- 指针数组中的意外结果
- 使用指针访问数组元素时出现意外结果
- 使用 sprintf 和 %g 将双精度转换为字符串的意外结果
- C++:比较运算符>和字符串文本的意外结果
- 具有意外结果的 C++ 闭包
- yaml-cpp 比较的意外结果
- 每次都出现意外结果
- 在 Qt 中解析嵌套的 JSON 时出现意外结果(数组不存在)
- 如何避免 std::abs 的意外结果?
- 使用嵌套 if 语句的意外结果
- A ^= B ^= A ^= B;C# Visual Studio 中的意外结果
- 逻辑错误,我将获得意外结果
- 在 c++ 中使用异步的意外结果
- 从函数的返回值将元素C++存储到 std::vector 中时出现意外结果
- 执行递增和递减时"cout"链接会产生意外结果
- OpenCL - 内核方法返回意外结果
- C++使用 std::get_time 解析 YYMMDD ISO 8601 日期字符串会得到意外结果