Open GrabYourPitchforks opened 5 years ago
Are these conversions needed often enough to deserve an API? I would not feel bad to recommend using MemoryMarshal.Cast
for the few rare cases where these conversions are needed.
@jkotas I think the concern with MemoryMarshal.Cast
is that the safety/portability is unclear. I have seen the comments added to the documentation, but they don't inspire confidence as they are now. I imagine other, including @GrabYourPitchforks, feel the same way.
Another way of looking at it is that it just "feels sketchy" using an assumed-safe part of MemoryMarshal
when you know other parts are unsafe depending on the context.
I believe the best developer ergonomics arise from the most obvious possible separation of safe and unsafe operations. The usual abstraction for separation of APIs is between class
es.
I understand the theory about why these APIs may be better.
My concern is that the scenario that these APIs cover is super rare. For example, I do not see a single place in CoreFX where these APIs can be used. If the low-level API like this cannot be used in CoreFX itself. it suggests that the API is useless.
Low/zero-allocation binary serialization and deserialization is my main use case for this kind of stuff.
Low/zero-allocation binary serialization and deserialization is my main use case for this kind of stuff.
There's no arbitrary conversion to ROS<byte>
as part of this proposal, so I don't think it helps the binary serialization scenario much. It would be mainly to allow some forms of variance that right now require calls to the unsafe MemoryMarshal.Cast
API. For instance:
ReadOnlySpan<uint>
to a Span<int>
.MemoryExtensions.SequenceCompareTo
.DataFrame
set of APIs.
This proposal is to make safe, simple APIs for things that would've been allowed using array variance. For example, it's fine to convert between
byte[]
andsbyte[]
. The APIs proposed here are safe, will always succeed, and are zero-cost (reinterpret_cast<T>
equivalent). The general idea is to avoid requiring developers to call unsafeMemoryMarshal
APIs in order to achieve these conversions.In particular, there are no APIs that go from arbitrary
T
to these primitive integral types, since that would run afoul of https://github.com/dotnet/corefx/issues/27094. Additionally, this proposal does not include APIs which would cause the resulting span to have a different length, as that would result in endianness issues and would require processing beyond a simplereinterpret_cast<T>
. TheMemoryMarshal.Cast
andMemoryMarshal.AsBytes
APIs remain available to callers who really need that scenario.