Permit stackalloc
in nested contexts
Note
This article is a feature specification. The specification serves as the design document for the feature. It includes proposed specification changes, along with information needed during the design and development of the feature. These articles are published until the proposed spec changes are finalized and incorporated in the current ECMA specification.
There may be some discrepancies between the feature specification and the completed implementation. Those differences are captured in the pertinent language design meeting (LDM) notes.
You can learn more about the process for adopting feature speclets into the C# language standard in the article on the specifications.
Stack allocation
We modify the section Stack allocation (ยง22.9) of the C# language specification to relax the places when a stackalloc
expression may appear. We delete
local_variable_initializer_unsafe
: stackalloc_initializer
;
stackalloc_initializer
: 'stackalloc' unmanaged_type '[' expression ']'
;
and replace them with
primary_no_array_creation_expression
: stackalloc_initializer
;
stackalloc_initializer
: 'stackalloc' unmanaged_type '[' expression? ']' array_initializer?
| 'stackalloc' '[' expression? ']' array_initializer
;
Note that the addition of an array_initializer to stackalloc_initializer (and making the index expression optional) was an extension in C# 7.3 and is not described here.
The element type of the stackalloc
expression is the unmanaged_type named in the stackalloc expression, if any, or the common type among the elements of the array_initializer otherwise.
The type of the stackalloc_initializer with element type K
depends on its syntactic context:
- If the stackalloc_initializer appears directly as the local_variable_initializer of a local_variable_declaration statement or a for_initializer, then its type is
K*
. - Otherwise its type is
System.Span<K>
.
Stackalloc Conversion
The stackalloc conversion is a new built-in implicit conversion from expression. When the type of a stackalloc_initializer is K*
, there is an implicit stackalloc conversion from the stackalloc_initializer to the type System.Span<K>
.
C# feature specifications