Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Span<T>(ref T obj) constructor #24615

Closed
bbarry opened this issue Jan 8, 2018 · 8 comments
Closed

Add Span<T>(ref T obj) constructor #24615

bbarry opened this issue Jan 8, 2018 · 8 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Memory
Milestone

Comments

@bbarry
Copy link

bbarry commented Jan 8, 2018

It is a small annoyance that to use a span/readonly span with a single instance of a value type you have to mark the assembly as unsafe (or call some helper code that does so)...

void unsafe Foo(ref MyStruct thing)
{
    var myStructSpan = new Span<MyStruct>(Unsafe.AsPointer(ref thing), 1);
    ref var component = ref myStructSpan.AsBytes().Slice(6, 11).NonPortableCast<byte, OtherStruct>()[0];
    // work with component...
}

It would be nice if I had a constructor that did this for me:

public unsafe Span(ref T item)
{
    if (SpanHelpers.IsReferenceOrContainsReferences<T>())
        ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
    _length = 1;
    _pinnable = null;
    _byteOffset = new IntPtr(Unsafe.AsPointer(ref item));
}

And same for ReadOnlySpan<T>

Or is there a better way to do this?

@jkotas
Copy link
Member

jkotas commented Jan 9, 2018

new Span<MyStruct>(Unsafe.AsPointer(ref thing), 1);

This is not doing GC tracking correctly. It is not ok to call Unsafe.AsPointer on ref that is not otherwise pinned. It will cause intermittent crashes.

@bbarry
Copy link
Author

bbarry commented Jan 9, 2018

I think that is a problem for the caller, just like it is for the pointer ctor and DangerousCreate().

This ctor would be at least as safe as the pointer one.

@jkotas
Copy link
Member

jkotas commented Jan 9, 2018

@VSadov What were the problems with wrapping locals in Span?

@sharwell
Copy link
Member

sharwell commented Jan 9, 2018

📝 Related to dotnet/csharplang#992

@VSadov
Copy link
Member

VSadov commented Jan 9, 2018

There is a problem with wrapping a ref parameter.
If that is allowed then many currently allowed patterns would be errors.

For example any time a local is passed by ref to a method that returns span, that span would be not returnable.

@VSadov
Copy link
Member

VSadov commented Jan 11, 2018

We discussed some support for wrapping single variable into a span. The issue gets pretty complex when you need to ensure life times.

It seems simple - if you wrap a local, then the resulting span value cannot leave the local's scope, if you wrap a heap location, then it can escape anywhere.

Where it becomes a problem is when ref parameters/returns/local are involved.

  • Can I wrap a ref parameter in a span and return it back to the caller? What if it was passing me a reference to a local?
  • If I pass a reference to a local to a method and it returns back a span, should I consider a possibility that the span wraps one of my local?
  • if the answers to both cases above are "No" (and that is the case right now), then how the proposed Span<T>(ref T obj) could work?

Span<T>(ref T obj) or similar helper cannot be treated as ordinary method, since it breaks the established expectations.

We may need a special language feature that specificaly "takes a ref and wraps it in a span", and we will track result as not escapable, unless we are sure the input ref was a heap ref.

Basically - this functionality may be introduced, but that would not be via a call to an ordinary method/constructor.

@VSadov
Copy link
Member

VSadov commented Jan 11, 2018

I guess the comment would be more useful in the discussion for dotnet/csharplang#992

@bbarry
Copy link
Author

bbarry commented May 11, 2018

Noticed MemoryMarshal.CreateSpan<T>(ref T reference, int length) that appears to do what I want. With that api I think this is good to close.

@bbarry bbarry closed this as completed May 11, 2018
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Memory
Projects
None yet
Development

No branches or pull requests

5 participants