You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<!-- The following restrictions apply to C# 7.3, they are relaxed in C# 8 -->
3296
-
A *stackalloc_expression* is only permitted in two contexts:
3297
-
3298
-
1. The initializing *expression*, `E`, of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)); and
3299
-
2. The right operand *expression*, `E`, of a simple assignment ([§12.21.2](expressions.md#12212-simple-assignment)) which itself occurs as a *expression_statement* ([§13.7](statements.md#137-expression-statements))
3300
-
3301
-
In both contexts the *stackalloc_expression* is only permitted to occur as:
3302
-
3303
-
- The whole of `E`; or
3304
-
- The second and/or third operands of a *conditional_expression* ([§12.18](expressions.md#1218-conditional-operator)) which is itself the whole of `E`.
3305
-
<!-- End of C# 7.3 restrictions -->
3306
-
3307
3294
The *unmanaged_type* ([§8.8](types.md#88-unmanaged-types)) indicates the type of the items that will be stored in the newly allocated location, and the *expression* indicates the number of these items. Taken together, these specify the required allocation size. The type of *expression* shall be implicitly convertible to the type `int`.
3308
3295
3309
3296
As the size of a stack allocation cannot be negative, it is a compile-time error to specify the number of items as a *constant_expression* that evaluates to a negative value.
@@ -3318,14 +3305,12 @@ When a *stackalloc_initializer* is present:
3318
3305
3319
3306
Each *stackalloc_element_initializer* shall have an implicit conversion to *unmanaged_type* ([§10.2](conversions.md#102-implicit-conversions)). The *stackalloc_element_initializer*s initialize elements in the allocated memory in increasing order, starting with the element at index zero. In the absence of a *stackalloc_initializer*, the content of the newly allocated memory is undefined.
3320
3307
3321
-
The result of a *stackalloc_expression* is an instance of type `Span<T>`, where `T` is the *unmanaged_type*:
3308
+
If a *stackalloc_expression* occurs directly as the initializing expression of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), where the *local_variable_type* is either a pointer type ([§23.3](unsafe-code.md#233-pointer-types)) or inferred (`var`), then the result of the *stackalloc_expression* is a pointer of type `T*` (§23.9). In this case the *stackalloc_expression* must appear in unsafe code. Otherwise the result of a *stackalloc_expression* is an instance of type `Span<T>`, where `T` is the *unmanaged_type*:
3322
3309
3323
3310
-`Span<T>` ([§C.3](standard-library.md#c3-standard-library-types-not-defined-in-isoiec-23271)) is a ref struct type ([§16.2.3](structs.md#1623-ref-modifier)), which presents a block of memory, here the block allocated by the *stackalloc_expression*, as an indexable collection of typed (`T`) items.
3324
3311
- The result’s `Length` property returns the number of items allocated.
3325
3312
- The result’s indexer ([§15.9](classes.md#159-indexers)) returns a *variable_reference* ([§9.5](variables.md#95-variable-references)) to an item of the allocated block and is range checked.
3326
3313
3327
-
> *Note*: When occurring in unsafe code the result of a *stackalloc_expression* may be of a different type, see ([§23.9](unsafe-code.md#239-stack-allocation)). *end note*
3328
-
3329
3314
Stack allocation initializers are not permitted in `catch` or `finally` blocks ([§13.11](statements.md#1311-the-try-statement)).
3330
3315
3331
3316
> *Note*: There is no way to explicitly free memory allocated using `stackalloc`. *end note*
Copy file name to clipboardexpand all lines: standard/unsafe-code.md
+1-3
Original file line number
Diff line number
Diff line change
@@ -1049,9 +1049,7 @@ When the outermost containing struct variable of a fixed-size buffer member is a
1049
1049
1050
1050
See [§12.8.22](expressions.md#12822-stack-allocation) for general information about the operator `stackalloc`. Here, the ability of that operator to result in a pointer is discussed.
1051
1051
1052
-
In an unsafe context if a *stackalloc_expression* ([§12.8.22](expressions.md#12822-stack-allocation)) occursastheinitializingexpressionofa*local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), wherethe*local_variable_type*iseitherapointertype ([§23.3](unsafe-code.md#233-pointer-types)) orinferred (`var`), thentheresultofthe*stackalloc_expression*isapointeroftype `T *` tobebeginningoftheallocatedblock, where `T` isthe *unmanaged_type* ofthe *stackalloc_expression*.
When a *stackalloc_expression* occurs as the initializing expression of a *local_variable_declaration* ([§13.6.2](statements.md#1362-local-variable-declarations)), wherethe*local_variable_type*iseitherapointertype ([§23.3](unsafe-code.md#233-pointer-types)) orinferred (`var`), theresultofthe*stackalloc_expression*isapointeroftype `T*`, where `T` isthe *unmanaged_type* ofthe *stackalloc_expression*. Inthiscasetheresultisapointertobebeginningoftheallocatedblock.
0 commit comments