gpt4 book ai didi

c# - 为什么会发生 CLR 异常 FatalExecutionEngineError?

转载 作者:IT王子 更新时间:2023-10-29 04:44:38 26 4
gpt4 key购买 nike

我们正在使用一个封装数值的结构,我发现当在表达式中使用该结构的可空版本时,会发生 FatalExecutionEngineError:

Additional information: The runtime has encountered a fatal error. The address of the error was at 0x729c1e04, on thread 0x52d8. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

我正在使用 Visual Studio Premium 2013 Update 3这是源代码(C#,目标 .NET Framework 4.5):

using System;
using System.Globalization;
namespace ConsoleApplication4
{
public struct Number
{
ValueType _val;

private Number(double val)
{
this._val = val;
}

public static implicit operator double(Number val)
{
return Convert.ToDouble(val._val, CultureInfo.InvariantCulture);
}

public static implicit operator Number(double val)
{
return new Number(val);
}
}

class Program
{
static void Main(string[] args)
{
Number? b = 1.2;
var c = b - 1.2;

Number b1 = 1.2;
var c1 = b1 - 1.2;
}
}
}

请注意,添加这个可以解决问题,所以这并不紧急,但我很想知道为什么会出现这个问题。

public static implicit operator double(Number? val)
{
return Convert.ToDouble(val.GetValueOrDefault()._val, CultureInfo.InvariantCulture);
}

最佳答案

这看起来像是一个编译器错误。问题发生在 Main 的第二行。

        Number? b = 1.2;
var c = b - 1.2; // The problem lies here

请注意 VS2013 生成的 IL,问题在于 IL_005C 和周围的代码,这是不必要的生成:

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// Code size 116 (0x74)
.maxstack 2
.locals init (valuetype [mscorlib]System.Nullable`1<valuetype Test.Number> V_0,
valuetype [mscorlib]System.Nullable`1<float64> V_1,
valuetype [mscorlib]System.Nullable`1<valuetype Test.Number> V_2,
valuetype [mscorlib]System.Nullable`1<float64> V_3,
valuetype [mscorlib]System.Nullable`1<float64> V_4)

// Number? b = 1.2;
IL_0000: nop
IL_0001: ldloca.s V_0 //b
IL_0003: ldc.r8 1.2
IL_000c: call valuetype Test.Number Test.Number::op_Implicit(float64)
IL_0011: call instance void valuetype [mscorlib]System.Nullable`1<valuetype Test.Number>::.ctor(!0)
IL_0016: nop
IL_0017: ldloc.0
IL_0018: stloc.2 // b

// var c = b - 1.2;
IL_0019: ldloca.s V_2 // b
IL_001b: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype Test.Number>::get_HasValue()
IL_0020: brtrue.s IL_002d
IL_0022: ldloca.s V_3
IL_0024: initobj valuetype [mscorlib]System.Nullable`1<float64>
IL_002a: ldloc.3
IL_002b: br.s IL_003e
IL_002d: ldloca.s V_2
IL_002f: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype Test.Number>::GetValueOrDefault()
IL_0034: call float64 Test.Number::op_Implicit(valuetype Test.Number)

// Um, what? First part of compiler bug is that it's needlessly creating a nullable float
IL_0039: newobj instance void valuetype [mscorlib]System.Nullable`1<float64>::.ctor(!0)
IL_003e: nop
IL_003f: stloc.3
IL_0040: ldloca.s V_3
IL_0042: call instance bool valuetype [mscorlib]System.Nullable`1<float64>::get_HasValue()
IL_0047: brtrue.s IL_0055
IL_0049: ldloca.s V_4
IL_004b: initobj valuetype [mscorlib]System.Nullable`1<float64>
IL_0051: ldloc.s V_4
IL_0053: br.s IL_0071
IL_0055: ldloca.s V_3

// Here's the real bug, though. It's passing float64 to a the op_Implicit that is expecting a Number struct
IL_0057: call instance !0 valuetype [mscorlib]System.Nullable`1<float64>::GetValueOrDefault()
IL_005c: call float64 Test.Number::op_Implicit(valuetype Test.Number)
IL_0061: conv.r8


IL_0062: ldc.r8 1.2
IL_006b: sub
IL_006c: newobj instance void valuetype [mscorlib]System.Nullable`1<float64>::.ctor(!0)
IL_0071: nop
IL_0072: stloc.1
IL_0073: ret
} // end of method Program::Main

Roslyn(也是使用它的 VS14 CTP)生成不存在此问题的不同 IL。代码几乎相同,只是它省略了 IL_0039IL_0061 之间的 IL。

关于c# - 为什么会发生 CLR 异常 FatalExecutionEngineError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25510837/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com