4

考虑以下方法(小提琴):

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];
}

我不明白为什么param = stackalloc int[10];会产生错误:

stackalloc不能在此上下文中使用类型为“Span”的表达式的结果,因为它可能会暴露在包含方法之外

Span是一个ref struct但是(尽管它的名字)它仍然是一个值类型,所以任何修改param都不会反映在调用者对象上。

我认为是param一个具有初始值的局部变量,我不明白为什么test2编译而test没有。

stackalloc int[10]in的返回值如何test逃出方法的作用域?

4

1 回答 1

4

Sinatr 在评论中发布了一个链接(此处为相关部分),帮助我将整个代码置于Span 安全的上下文中。

在方法test中,参数param可以安全返回,因为我们可以假装它像一个局部变量,使用调用者给定的值初始化(因此,在方法外部,可以安全返回)。

当一个局部被标记为安全返回时,编译器将阻止对它进行任何不安全返回的赋值(stackalloc表达式可以安全地转义到方法的顶部范围,但显然不能安全返回)。

该方法为 void 的事实并不重要(对于我作为提问者而言,对于编译器也不重要),因为这条规则是通用的(我认为处理这些极端情况没有多大好处)。

为了完整起见,此代码无法编译:

void test2(Span<int> param)
{
    //Fail, because local is marked safe to return
    Span<int> local = param;
    local = stackalloc int[10];
}

这是我一直在寻找的缺失部分。

于 2021-04-28T13:43:21.237 回答