Lifetime tracking considerations for MemoryMarshal.CreateSpan #64750
Replies: 3 comments 5 replies
-
There are always going to be certain users with certain cases where they may want to break or violate the current language rules. There may even be other languages (F#, VB, etc) that don't get support for the new lifetime rules at the same time as C# (or possibly even ever). I think an API that tracks the lifetime of the |
Beta Was this translation helpful? Give feedback.
-
They are some examples of methods that use ref T and length. For example CompareStringIgnoreCase or in my CRC32 table computation. In the case you want to call some |
Beta Was this translation helpful? Give feedback.
-
For me there are two separate parts to this discussion. The first is the language side. The language is taking a minor compatibility break with the The second part is the runtime side who defines APIs like I share the feeling that the uses of I think the best path forward here would be looking to define analyzers that could spot the cases that would be better off as |
Beta Was this translation helpful? Give feedback.
-
Opening this discussion here as suggested by @jaredpar, so it's public to anyone given it's nothing internal.
I've been thinking about the whole "what do we do with
MemoryMarshal.CreateSpan
issue", and came to the conclusion that we might have made an assumption on its usage that's not necessarily correct. To recap, the current proposal as it stands (see dotnet/csharplang#5602) makes the following distinction between what is legal today and what "needs to remain" legal tomorrow, specifically with respect toCreateSpan
. We have the following, as per Jared's proposal:Now, the point I'm trying to make here is that I'm not convinced the second part is actually true. Do we really need
CreateSpan
not to track the lifetime of the target reference? It seems to me that we might have overlooked the real reason why that API is so crucial to people like eg. @tannergooding, me, and other runtime developers, and that is that this API takes an arbitrary length. This alone would still be enough to make it (1) absolutely crucial to have and (2) not safe, but I don't think the "not tracking the lifetime" bit is necessary a critical component of this. Yes, right now there's also the fact that it lets you do things not expressable in C# (eg. escaping a struct field), but the point is that doing so will already be legal in C# 11 with proper annotations. In other words, I'm thinking that even if this API started properly tracking the lifetime of the target reference, it would still keep being perfectly useful in the scenarios where it's used today, and where you most definitely would want to add proper lifetime annotations in C# 11 as well. To make some examples:stackalloc
buffer, then you surely wouldn't return it to the caller, so it being tracked is ok.Span<T>(ref T)
constructor anyway.In all other cases where people (myself included) are using this API to trick the compiler and return a ref to an instance member of a struct, well then once C# 11 is out you'd most definitely want to refactor all those places anyway to give callers proper annotations and guardrails so they don't end up with dangling references anyway. This would be the case in eg. all cases where people today are handrolling managed fixed buffer types, you'd be perfectly fine with the API also tracking the lifetime in those scenarios as well.
So basically, unless I'm missing something, I'm now getting convinced that breaking and adding proper lifetime tracking to
CreateSpan
, as its main point (the arbitrary length) would still be available, and the language would allow you to not need it anymore for the tricks where it's needed today. Granted, in case keeping it completely unsafe didn't require additional work then I guess we could also just leave it as is, but in case it was easier to make it consistent with the rules anywhere else in C# 11, I'm thinking it might be actually worth considering taking the breaking change here. I just can't really think of cases right now where this could actually be an issue 🤔cc. @stephentoub @davidwrighton (feel free to tag anyone else if needed)
Beta Was this translation helpful? Give feedback.
All reactions