runtime: S.R.CS.Unsafe: Add unsafe operations for ref returns and locals
Roslyn is adding support for ref returns and locals (https://github.com/dotnet/roslyn/issues/118). S.R.CS.Unsafe should provide operations that allow taking advantage of ref returns and locals in unsafe code.
public static class Unsafe
{
// Reinterprets the given reference as a reference to a value of type TTo
public static ref TTo As<TFrom,TTo>(ref TFrom source);
// Add element offset to the given reference.
public static ref T Add<T>(ref T source, int elementOffset);
// Subtract element offset to the given reference.
public static ref T Subtract<T>(ref T source, int elementOffset);
// Determines whether the specified references point to the same location.
public static bool AreSame<T>(ref T a, ref T b);
}
Edit: Updated with the revised proposal
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 9
- Comments: 52 (50 by maintainers)
Commits related to this issue
- Add unsafe operations for ref returns and locals Fixes #10451 — committed to jkotas/corefx by jkotas 8 years ago
- Add unsafe operations for ref returns and locals Fixes #10451 — committed to jkotas/corefx by jkotas 8 years ago
- Add unsafe operations for ref returns and locals Fixes #10451 — committed to jkotas/corefx by jkotas 8 years ago
- Add unsafe operations for ref returns and locals (#10540) Fixes #10451 — committed to dotnet/corefx by jkotas 8 years ago
Here is the updated proposal with feedback incorporated:
<TFrom,TTo>order forAsas it is preferred by more people. Renaming the generic arguments for clarity.intoverloads for Add/Subtract are needed to make this reasonably usable today.IntPtroverloads for Add/Subtract can be added later without any harm if/once native int becomes better supported in C#.Subtract(ref,int)for convenience, even though it is redundant.Subtract(ref,ref)for now because of it is not very useful with byref locals and returns anyway, and there are naming and design issues around it.ReferenceEqualstoAreSame. I have checked about a good name with @KrzysztofCwalina and he suggested this name. It is being used for similar concepts in other places and I like it the most out of all the options discussed.Maybe just add * and / to IntPtr? I think IntPtr should behave like any other integer type as much as possible. I saw proposed C# language changes about that on the Roslyn Github presence.
The pointer difference representation can safely be IntPtr on all platforms. The CLR can just promise to make that work. I see no issues with that.
The null refs cannot be manufactured in C# directly, but they are possible to manufacture by unsafe code. They can be checked for null using
Unsafe.AsPointer(ref valueRef) == null.Ha ha, no thanks. I think I’ll start hating fluent APIs with a passion. They have their uses but these days they’re more like abuses.
Thank you for a great feedback! I like the suggestions.
Byrefs on stack are implicitly pinned, so it can be used to assert that it is safe to convert to raw pointer without pinning - example from CoreCLR. Unfortunately, there is no way to implement it in portable way. It would have to be runtime or platform specific that is not pretty given the current shape of library. If it keeps showing up as needed API, it should be looked into as separate issue.
I agree that it is useful operation to have. BTW: It is less useful with the current byref locals and returns than one may think because of the single assignment limitations of byref locals. I have noticed in my experiments that one tends to operate on indices and then convert to byref as the last step and never go back - the style of the pointer math is different from unmanaged pointers.
It may be be also nice to have Subtract variant that takes elementOffset for convenience and symmetry with Add.
So the updated proposal is:
More suggestions for refinements are welcomed.
Including @jamesqo @KrzysztofCwalina that I forgot to include yesterday.
Nope, they cannot. The equivalents that you show are incorrect because the use of
AsPointerintroduces an intermediary unmanaged pointer.We already have a
refreturning method -AsRef. It seems to me that it would make sense that the new method is also calledAsRef.Seems confusing. I can imagine one asking “Does this method compare references or does it compare the referenced values?”.