How-To's

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:

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!

image description