Back to Csharplang

C# Language Design Meeting for April 10th, 2023

meetings/2023/LDM-2023-04-10.md

latest3.1 KB
Original Source

C# Language Design Meeting for April 10th, 2023

Agenda

Quote of the Day

  • "As a Tanner of the world"

Discussion

Fixed Size Buffers

https://github.com/dotnet/csharplang/pull/7064
https://github.com/dotnet/csharplang/issues/1314

Continuing from last time, we took a look at the second of the possible fixed size buffer approaches today. This one is much simpler and is based on only exposing Span and ReadOnlySpan types to the user, instead of BufferX<T> types. This ensures that users don't have new types to think about and can keep operating in terms of the types they already know. It also allows changing the size of a fixed-size buffer to not be a binary-breaking change, as the only publicly-exposed types are Span and ReadOnlySpan, neither of which has an associated fixed length. This simplicity does bring some of its own downsides too, though:

  • That binary break could be a desired outcome: if a public fixed size buffer shrinks, it's important for that to break the API of anyone who was accessing memory that no longer exists.
    • On this note, we don't currently have anywhere that we plan to expose public fixed size buffers, outside native interop scenarios.
  • How do other languages consume these types? Do they have to understand an additional C# concept layered on top of the general runtime pattern?
  • Does this stifle our future language design space? We could want to reason about fixed-size arrays in the future, for example a List<int[4]>, or even going further and allowing const generics as in List<int[TSize]>.
    • Users might also simply want to pass these buffers around. If the buffer is typed as Span or ReadOnlySpan, then size information is elided and compile-time bounds checking can be lost.

Additionally, using Span and ReadOnlySpan as the user-facing types doesn't prevent users from defining their own fixed size buffer types, as InlineArrayAttribute is a runtime feature. Should C# add support for consuming such types as if they are fixed size buffers, even if we don't int[4] as one? This has its own set of complications. We're a bit concerned about whether it's worth the effort: how many users are actually going to define these types? And if they do, will these types conflict with each other? Unlike tuples, we somewhat expect that fixed size buffers could be hundreds of elements long; even if the BCL were to define the first 32 sizes, there's still a good chance that two fixed size buffers from different assemblies would be conflicting definitions, even though they wrap the same type and have the same length. Despite these concerns, though, we think that there's enough benefit for the BCL in supporting these types that we should do so in C#. Next time, we will pick this up again and try to determine whether we will have specific syntax for easily defining these types of buffers in the language itself (such as int[4]) or not.

Conclusion

C# will support using fixed size buffer types as if they are buffers. We will think more about whether to have syntactic sugar for defining them next time.