Span<T>
가능한 경우 힙 할당을 피하기 위해 라이브러리를 리팩토링하고 있지만 이전 프레임 워크를 대상으로하므로 일반적인 대체 솔루션도 구현하고 있습니다. 그러나 지금 이상한 문제가 발견되어 .NET Core 3에서 버그를 발견했는지 아니면 불법적 인 일을하고 있는지 확실하지 않습니다.
문제:
// This returns 1 as expected but cannot be used in older frameworks:
private static uint ReinterpretNew()
{
Span<byte> bytes = stackalloc byte[4];
bytes[0] = 1; // FillBytes(bytes);
// returning bytes as uint:
return Unsafe.As<byte, uint>(ref bytes.GetPinnableReference());
}
// This returns garbage in .NET Core 3.0 with release build:
private static unsafe uint ReinterpretOld()
{
byte* bytes = stackalloc byte[4];
bytes[0] = 1; // FillBytes(bytes);
// returning bytes as uint:
return *(uint*)bytes;
}
흥미롭게도 ReinterpretOld
.NET Framework 및 .NET Core 2.0에서 잘 작동하지만 결국 행복 할 수 있습니다.
Btw. ReinterpretOld
.NET Core 3.0에서도 약간 수정하여 수정할 수 있습니다.
//return *(uint*)bytes;
uint* asUint = (uint*)bytes;
return *asUint;
내 질문:
버그입니까, 아니면 ReinterpretOld
우연히 이전 프레임 워크에서 작동합니까? 수정 사항도 적용해야합니까?
비고 :
- 디버그 빌드는 .NET Core 3.0에서도 작동합니다.
- 나는 적용하는 시도
[MethodImpl(MethodImplOptions.NoInlining)]
를ReinterpretOld
하지만 아무런 영향을 미치지 않습니다.
stackalloc
(즉, 할당 된 공간을
return Unsafe.As<byte, uint>(ref bytes[0]);
또는return MemoryMarshal.Cast<byte, uint>(bytes)[0];
-사용할 필요가 없습니다GetPinnableReference()
. 하지만, 다른 비트에보고