Skip to content

[API Proposal]: Missing scoped ref readonly and in reference handling at Unsafe reference #104909

Open
@redknightlois

Description

@redknightlois

Background and motivation

The Unsafe class provides various methods for working with references in an unsafe manner for ref T. However, there are missing operations for handling ref readonly references, such as AddByteOffset. Currently, there is a need to use Unsafe.AsRef to convert ref readonly to ref, which adds unnecessary steps.

Proposal:

I propose the addition of ref readonly reference handling operations to the Unsafe class where the guarantees are still valid in order to avoid users to use Unsafe.AsRef when those guarantees could introduce subtle bugs. Specifically, unless I am missing something, methods such as AddByteOffset should directly support ref readonly references without requiring a call to Unsafe.AsRef.

Extending the Unsafe class to support ref readonly aligns with the existing pattern used alongside the Vector API which supports the used of both ref and readonly ref in operations where no side-effects exist.

API Proposal

public static ref readonly T AddByteOffset<T>(scoped ref readonly T source, IntPtr byteOffset);
public static ref readonly T SubstractByteOffset<T>(scoped ref readonly T source, IntPtr byteOffset);
public static ref readonly T Add<T>(scoped ref readonly T source, int offset);
public static ref readonly T Substract<T>(scoped ref readonly T source, int offset);

API Usage

This is how I do this now:

internal static int CompareAvx256(scoped in byte p1, scoped in byte p2, int size)
{
    ref byte bpx = ref Unsafe.AsRef(in p1);
    ref byte bpy = ref Unsafe.AsRef(in p2);
    ref byte bpxEnd = ref Unsafe.AddByteOffset(ref bpx, size);
    ....    
}

We should be able to keep the ref readonly guarantee on those references.

internal static int CompareAvx256(scoped in byte p1, scoped in byte p2, int size)
{
    ref readonly byte bpx = ref readonly p1;
    ref readonly byte bpy = ref readonly p2;
    ref readonly byte bpxEnd = ref Unsafe.AddByteOffset(ref readonly bpx, size);
    ....    
}

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.Runtime.CompilerServicesneeds-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions