-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
API proposal: Unsafe.NullRef, IsNullRef #31170
Comments
Bwahaha, this lives! 😈 Though upon further thought I'm curious as to whether for usability's sake it would be better to take "ref" instead of "in". I'm wondering if there will be pits of failure where folks pass non-refs to this method, the compiler fixes up the call site to create a reference to the copied local, and the method always returns false. |
Agree. |
I think it should take
Basically - most cases that |
* Dictionary avoid second bounds check in Get methods * Add NullRef methods to Unsafe Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
At the same time, An analyzer would likely be sufficient to catch the issues of passing an |
API review - This really should be |
FWIW, there are two reasons why this should take
|
Many of the APIs were added before
This is true for any usage of Personally, I would much rather have an analyzer enabled that calls out places where I may be doing inefficient things than have to insert the equivalent of However, maybe as an alternative, we could have both |
I have written quite a bit of code against S.R.CS.Unsafe and I have not found this to be a nuisance. I find the unsafe byref-arithmetic with
Yes, this sounds better to me. |
What about
|
@broudy3 what's the scenario for caring about 'out'? Edit: some further thoughts - methods that accept 'out' parameters basically have a contract "I'll write to this address before the method returns." It would be a caller error to pass null for these addresses, akin to saying "in the x64 calling convention, I'm expecting a struct return value but passing nullptr for rcx." The method should expect to AV upon returning. |
That's really the C# contract however, not necessarily the IL contract. There are plenty of native methods, for example, which take a |
I agree, but we're talking about an API specifically for C# callers. |
and F#, IL, C++/CLI, or any of the other languages the framework supports. It is incredibly niche, but one you get into interop land, it's entirely reasonable, and if we are adding a version for |
That sounds like a good argument against adding it, especially since it's already doable by stringing together existing APIs. :) In IL and C++/CLI you can already trivially compare the reference against null using existing language syntax. No special function needed. I don't know enough about F# to make a statement there.
I'm still not personally convinced on the utility of the in function. But I'm willing to cede that point. |
+1 .
+1. |
FWIW, we do seem to have a bunch more folks using byref arithmetic in high-performance code bases. I know that Tanner has been fielding questions along these lines lately. Is there any chance we might get first-class language support to make these scenarios a bit less error-prone? It should also obviate the need for some of the APIs as proposed here. Strawman example: public unsafe void DoIt(int* ip)
{
// 'ip' is non-gc tracked pointer to int
int* jp = i + 1; // jp points to an address 4 bytes after ip
bool isNull = (ip == null);
int deref = *ip;
}
public unsafe void DoIt(int& ip)
{
// 'ip' is gc tracked pointer to int
int& jp = i + 1; // jp points to an address 4 bytes after ip, still gc-tracked
bool isNull = (ip == null);
int deref = *ip;
} One pit of failure from this is that the second example resembles a standard pointer, but it's a gc-tracked pointer. If you perform the arithmetic incorrectly you could end up making the GC very angry. But you already have that situation today if you use the |
This sounds like a proposal for https://github.com/dotnet/csharplang. I do not see one on this yet. |
FWIW, |
Is there anything blocking this from being marked |
This was API reviewed once already and sent back with the I agree that this is not critical for 5.0. |
Your API as proposed LGTM. |
namespace System.Runtime.CompilerServices
{
public class Unsafe
{
public bool IsNullRef<T>(ref T);
public ref T NullRef<T>();
}
} |
Proposed API
ref
cannot be null pointer in C#, but it is perfectly valid in IL.ref
containing null pointers are useful for low-level optimizations. For example, dotnet/coreclr#27195 uses them to make Dictionary lookups about 10% faster. There are several other examples in the .NET Core framework where we have usedref
containing null pointers.The Unsafe class does have building blocks that allow operations on null
ref
pointers (e.g.Unsafe.AsPointer<T>(null)
creates null ref), but it obfuscates the intent and it is not as straightforward and lean as it can be. The proposed APIs will make it easier.The text was updated successfully, but these errors were encountered: