Conversation
Ordinary arrays can be created through the following syntax:
```C#
new int[3]
new int[3] { 1, 2, 3 }
new int[] { 1, 2, 3 }
new[] { 1, 2, 3 }
```
We should allow stack allocated arrays be created through:
```C#
stackalloc int[3] // currently allowed
stackalloc int[3] { 1, 2, 3 }
stackalloc int[] { 1, 2, 3 }
stackalloc[] { 1, 2, 3 }
```
|
Skip zero init? Or not be considered for triggering for |
| The semantics of all cases is roughly the same as with arrays. | ||
| For example: in the last case the element type is inferred from the initializer and must be an "unmanaged" type. | ||
|
|
||
| NOTE: the feature is not dependent on the target being a `Span<T>`. It is just as applicable in `T*` case, so it does not seem reasonable to predicate it on `Span<T>` case. |
There was a problem hiding this comment.
What are the requirements on the target? Does it work for any type with void*, int length constructor?
(I assume that this is answered in the spec for the currently allowed case without initializer. The link to that spec may be helpful.)
There was a problem hiding this comment.
It works with any type that has implicit conversion from Span<T>.
There was a problem hiding this comment.
From the language semantics stackalloc T[size] expression has Span<T> type, unless it matches backwards-compatible pattern where it must have type T*.
The implementation will call well-known constructor Span<T>(void*, int). Essentially there is one "magic" type - Span<T> and one "magic" method Span<T>(void*, int), that we know about.
Other types opt-in by providing a conversion operator. It is more intentional than matching (void*, int) constructors on random types - who knows what they expect, is that always {ptr, size}, is that size in bytes on elements?
With Span<T> there could be no doubts on {ptr, size} part.
This is also how stackalloc always worked. - you could always participate by having a conversion from T* . Opting in via a conversion is not a new feature.
There was a problem hiding this comment.
Essentially there is one "magic" type -
Span<T>and one "magic" methodSpan<T>(void*, int), that we know about.
Ok, that make sense. I was under impression that you are somehow doing this without knowing about magic Span<T> type.
There was a problem hiding this comment.
We tried avoiding magic types, but arrived to a conclusion that for a robust pattern we would need one type - a generally accepted representation of {ptr, size} tuple.
And then realized, that Span<T> works just fine for that purpose :-)
There was a problem hiding this comment.
Since it's based on Span<T>, I assume I'd be able to write:
ReadOnlySpan<char> ros = stackalloc char[] { ch };
...? Today to do the same thing I need to write:
Span<char> s = stackalloc char[1];
s[0] = ch;
ReadOnlySpan<char> ros = s;
...|
|
||
| ## Drawbacks | ||
| [drawbacks]: #drawbacks | ||
|
|
There was a problem hiding this comment.
I like how there are no drawbacks :-)
There was a problem hiding this comment.
Well, implementing a feature has cost, but it is a kind of obvious drawback. Could not find any other.
|
Merging this, since there are Approvals and no known objections. |
In short: Ordinary arrays can be created through the following syntax:
We should allow stack allocated arrays be created through: