Consider the following methods (fiddle):
void test(Span<int> param)
{
//Fail, the stackalloc'ed buffer could be exposed.
param = stackalloc int[10];
}
void test2(Span<int> param)
{
//OK
Span<int> local = stackalloc int[10];
}
I don't understand why param = stackalloc int[10];
produces the error:
A result of a
stackalloc
expression of type 'Span' cannot be used in this context because it may be exposed outside of the containing method
Span
is a ref struct
but (despite its name) it is still a value-type so any modification to param
won't be reflected on the caller object.
I think of param
as a local variable with an initial value and I don't see why test2
compiles while test
doesn't.
How can the returned value of stackalloc int[10]
in test
escape the scope of the method?
Sinatr posted a link (here the relevant part) in the comments that helped me put the whole code in the context of Span safety.
In the method
test
the parameterparam
is safe to return because we can pretend it was like a local variable initialized with a value given by the caller (and thus, being external to the method, safe to return).When a local is marked safe to return, the compiler will prevent any assignment to it with values that are not safe to return (
stackalloc
expressions are safe to escape to the top scope of the method but are not safe to return, obviously).The fact that the method is void doesn't matter (neither to me as an asker, neither to the compiler) as this rule is general (I don't see much benefit from handling these corner cases).
For completeness, this code doesn't compile:
This was the missing piece I was looking for.