最近我在TryRoslyn上玩C#编译器,我遇到了一个奇怪的问题,即不等式检查被转换为大于一的.这是repro代码:
using System;
public class C {
public void M() {
if (Foo() != 0 || Foo() != 0)
{
Console.WriteLine("Hi!");
}
}
private int Foo() => 0;
}
Run Code Online (Sandbox Code Playgroud)
这是反编译器生成的代码:
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[module: UnverifiableCode]
public class C
{
public void M()
{
bool flag = this.Foo() != 0 || this.Foo() > 0; // this should be an != check
if (flag)
{
Console.WriteLine("Hi!");
}
}
private int Foo()
{
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
这是 repro的链接.为什么罗斯林会这样做; 这是一个错误吗?
我在玩了一段时间后对代码进行了一些观察:
这只发生在条件中的最后一个布尔表达式.例如,如果添加另一个||语句,它将仅在最后一次调用时发生Foo().
它也只发生在0,特别是; 如果你替换它1或其他一些数字,它将不会发生.
Eri*_*ert 11
反编译的代码是错误的; 这是反编译器中的错误,而不是编译器.生成的IL是正确的.仔细阅读IL.你明白为什么大于比较是正确的并且反编译是错误的吗?
至于为什么这个codegen只发生在操作员的右侧,我不记得了.如果你想在代码生成器中进行探索,它就在这里:
https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs
你想要方法EmitIsNonNullOrZero.
| 归档时间: |
|
| 查看次数: |
349 次 |
| 最近记录: |