-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Unsafe API for comparing byrefs as pointers #24729
Comments
Between?
|
Why |
Copy&paste mistake. Updated above. |
Could C# support the full set of comparison operators for ref types instead? The way those names read is unfortunate: I mentally read out a line of code like:
and I hear "if is below left" which is the opposite of what the conditional does... |
S.R.CS.Unsafe APIs are trying to have 1:1 mapping to IL instructions. IsBetween does not map to a single IL instruction. It is a convenience wrapper over pair of IsAbove+IsBelow calls. Having said that, we have violated this design principle in a few places when it has a demonstrated benefits. Do you have a good case where IsBetween would help significantly? |
Adding operators for byrefs is hard to fit into C# design. This applies to all pointer-like operations, not just comparison: add/subtract, casting, ... . If it was not the case, S.R.CS.Unsafe would not be really needed.
Can you think about a different name that would read better? |
I'll throw in I'll assume a standard |
Similar to the I don't have a strong use case |
The only argument for IsBetween that I can imagine is that it's a notoriously difficult check for the average developer to get correct. But at that point we're talking about callers that manipulate memory directly, and realistically I don't know who other than the BCL would ever be doing that. |
Something closer to Compare/CompareTo
|
We think these names align closer to the framework naming: public static class Unsafe
{
public static bool IsAddressLessThan<T>(ref T left, ref T right);
public static bool IsAddressGreaterThan<T>(ref T left, ref T right);
} |
Given that the GC can relocate the references during or after the call, how is possible to use this API correctly? If both references need to be pinned, we typically document that in the method name (similarly to I'd also like to confirm that this API really is unsafe. The answer might be wrong if references aren't pinned, but the method won't corrupt memory. |
If the references are not pinned, you have to make sure that both point into same object or array.
You are right that this API is not going to corrupt your memory. Unsafe here really means that you have to know what you are doing. here are other similar APIs on this type like |
It would be good to describe in the docs the things people need to know to use the API "safely". |
@KrzysztofCwalina See the devdoc at https://github.com/dotnet/corefx/blob/83f35ef9a79b5cd1412aeaad8d2cb84e1bfe73c4/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml#L211-L214. Do you think this is sufficient? |
@GrabYourPitchforks , is the API guaranteed to pin the inputs for the same array/object/span case? Otherwise a torn read could still give an undefined answer. |
@morganbr There is no risk of torn read. The GC moves all byrefs atomically. |
S.R.CS.Unsafe should provide operations that allow comparing byrefs. These operations in combination with C# support for ref locals reassigments (Roslyn feature in progress - https://github.com/dotnet/csharplang/blob/master/proposals/ref-local-reassignment.md) will allow significantly more efficient unsafe implementations of low-level algorithms.
For example, Span Reverse prototype done by @GrabYourPitchforks showed up to 30% performance improvements (dotnet/corefx#26381 (comment)).
Proposed API:
The text was updated successfully, but these errors were encountered: