.NET Tools
Essential productivity kit for .NET and game developers
C# 7.2 and 7.3 updates for stackalloc
The latest versions of ReSharper 2018.2 and Rider 2018.2 come with support for C# 7.3. In this series, we are looking at these new language features in C# 7.3. Today we will look at the array initializers in stackalloc.
This post is part of a series:
- Declaration expressions in initializers and queries
- Tuple equality
- Unmanaged, delegate and enum type constraints
- Ref local re-assignment
- Fixed pattern and simplified access to fixed size buffer elements
- C# updates for stackalloc
In C#, the stackalloc
keyword is used in an unsafe code context to allocate a block of memory on the stack. The stackalloc
operator is similar to the _alloca
function from the C language. This C# operator is used as a way of manually allocated memory buffers that can be used without type safety checks.
When do you need to use stackalloc?
In an average project, you probably won’t need this. For real-time sensitive scenarios (possibly video or audio), it gives better performance for working with small arrays storing data that is cached locally. In such cases, data is not allocated on the managed heap so no Garbage Collection (GC) is involved – you are only looking at a call to the unsafe array. Also, remember that stackalloc
does come with some additional costs with needing to zeroing the allocated memory. If that overhead is too high you can always look at using off-heap solutions for your needs.
Changes with stackalloc in C# 7.2
There are several changes around stackalloc
that were done for C# 7.2. Before C# 7.2 you could only use stackalloc
as an initializer of local pointer variable and only within unsafe context:
unsafe void M() { int* array = stackalloc int[1024]; }
Since C# 7.2, stackalloc is an expression and is valid in conditional expressions and assignment expressions outside of unsafe contexts:
void M(int size) { Span<byte> span = size <= 128 ? stackalloc byte[size] : new byte[size]; // ... span = stackalloc byte[128]; }
This example also shows that using stackalloc
as an expression is now convertible to Span<T>
type and also ReadOnlySpan<T>
. Also, that unsafe context is not required when stackalloc
expression type if converted to Span<T>
or ReadOnlySpan<T>
.
Changes with stackalloc in C# 7.3
Let’s look at using the new C# 7.3 feature for initializing arrays with stackalloc
. Initializing arrays in a safe code context has been around since the inception of C# as in the following:
var arr = new int[5] {1, 4, 9, 16, 25}; var arr2 = new int[] {1, 2, 4, 8}; var arr3 = new float[] {1.1F, 3.2F, 43.7F};
Using stackalloc
to create the same arrays would be written as:
int* pArr = stackalloc int[5] {1, 4, 9, 16, 25}; int* pArr2 = stackalloc int[] {1, 2, 4, 8}; float* pArr3 = stackalloc float[] {1.1F, 3.2F, 43.7F};
Conclusion
There have been a number of changes to stackalloc
that allows the C# operator to be used outside of the unsafe context, in an expression and also now allows for initialization of arrays. With the changes, more developers may find stackalloc
useful in their solutions when they need to work directly with the stack memory.
Download ReSharper 2018.2 now! Or give Rider 2018.2 a try. We’d love to hear your thoughts!