Consider the following code:
private static void Main(string[] args) { var ar = new double[] { 100 }; FillTo(ref ar, 5); Console.WriteLine(string.Join(",", ar.Select(a => a.ToString()).ToArray())); } public static void FillTo(ref double[] dd, int N) { if (dd.Length >= N) return; double[] Old = dd; double d = double.NaN; if (Old.Length > 0) d = Old[0]; dd = new double[N]; for (int i = 0; i < Old.Length; i++) { dd[N - Old.Length + i] = Old[i]; } for (int i = 0; i < N - Old.Length; i++) dd[i] = d; }
The result in Debug mode is: 100,100,100,100,100. But in Release mode it is: 100,100,100,100,0.
What is happening?
It was tested using .NET framework 4.7.1 and .NET Core 2.0.0.
This appears to be a JIT bug; I've tested with:
// ... existing code unchanged for (int i = 0; i < N - Old.Length; i++) { // Console.WriteLine(i); // <== comment/uncomment this line dd[i] = d; }
and adding the Console.WriteLine(i)
fixes it. The only IL change is:
// ... L_0040: ldc.i4.0 L_0041: stloc.3 L_0042: br.s L_004d L_0044: ldarg.0 L_0045: ldind.ref L_0046: ldloc.3 L_0047: ldloc.1 L_0048: stelem.r8 L_0049: ldloc.3 L_004a: ldc.i4.1 L_004b: add L_004c: stloc.3 L_004d: ldloc.3 L_004e: ldarg.1 L_004f: ldloc.0 L_0050: ldlen L_0051: conv.i4 L_0052: sub L_0053: blt.s L_0044 L_0055: ret
vs
// ... L_0040: ldc.i4.0 L_0041: stloc.3 L_0042: br.s L_0053 L_0044: ldloc.3 L_0045: call void [System.Console]System.Console::WriteLine(int32) L_004a: ldarg.0 L_004b: ldind.ref L_004c: ldloc.3 L_004d: ldloc.1 L_004e: stelem.r8 L_004f: ldloc.3 L_0050: ldc.i4.1 L_0051: add L_0052: stloc.3 L_0053: ldloc.3 L_0054: ldarg.1 L_0055: ldloc.0 L_0056: ldlen L_0057: conv.i4 L_0058: sub L_0059: blt.s L_0044 L_005b: ret
which looks exactly right (the only difference is the extra ldloc.3
and call void [System.Console]System.Console::WriteLine(int32)
, and a different but equivalent target for br.s
).
It'll need a JIT fix, I suspect.
Environment:
Environment.Version
: 4.0.30319.42000<TargetFramework>netcoreapp2.0</TargetFramework>
dotnet --version
: 2.1.1If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With