【问题标题】:How the compiler can prove that memory safety?编译器如何证明内存安全?
【发布时间】:2021-07-20 09:53:16
【问题描述】:

当我阅读Swift 编程语言:内存安全时,我被 Conflicting Access to Properties 部分弄糊涂了:

下面的代码显示重叠写入出现相同的错误 访问存储在全局中的结构的属性 变量。

var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy)  // Error 

在实践中, 大多数对结构属性的访问可以安全地重叠。为了 例如,如果上面示例中的变量holly 更改为 局部变量而不是全局变量,编译器可以证明 对结构的存储属性的重叠访问是 安全:

func someFunction() {
    var oscar = Player(name: "Oscar", health: 10, energy: 10)
    balance(&oscar.health, &oscar.energy)  // OK 
}

在上面的示例中,Oscar 的健康和能量作为两个输入输出参数传递给balance(_:_:)。编译器可以证明内存 安全性得以保留,因为两个存储的属性不交互 以任何方式。

编译器如何证明内存安全?

【问题讨论】:

  • 我经常从相反的角度想知道同样的问题,即为什么不能编译器在第一个示例中证明内存安全。当然,编译器知道全局变量和局部变量的内存布局,并且应该能够查看healthenergy 属性在任何一种情况下是否相互别名。我有一些猜测,但不是一个实际的答案。好问题。
  • 虽然这是一个有趣的问题,但我认为 SO 不是正确的论坛。我建议你在Swift forums 中提问,在那里你可以找到更熟悉编译器功能的专家。
  • 还在 Swift 论坛上创建了a topic

标签: ios swift


【解决方案1】:

在函数范围内使编译器可以确定哪些操作将在struct 上执行以及何时执行。编译器知道structs 是如何工作的,以及函数内的代码是如何以及何时(相对于函数被调用的时间)执行的。

在全局或更大范围内,编译器无法了解可能修改内存的内容和时间,因此无法确保安全。

【讨论】:

  • 你是说这是线程安全问题,而不是内存别名问题?
  • @ChipJarred 或这​​些东西的组合。
【解决方案2】:

这是因为多个线程。当“holly”是全局变量时,多个线程可以同时访问全局变量,你就有麻烦了。对于局部变量,该变量每次执行函数都存在一次。如果多个线程同时运行 someFunction(),每个线程都有自己的“oscar”变量,所以线程 1 的“oscar”变量不可能访问线程 2 的 oscar 变量。

【讨论】:

  • 如果这是一个线程安全问题,非结构值(数据竞争)有相同(或非常相似)的问题。我怀疑它与按引用传递有关,而不仅仅是像在 C 或 C++ 中那样在幕后传递指针。基本上,如果它只是关于数据竞争,那么任何对全局的引用,即使是单个的,都会有问题,并且是语言设计的不一致。我不确定实际的答案,但在我看来,要使其成为一致的语言设计,就必须是内存别名问题,而不仅仅是数据竞争问题。
  • 这个答案和 EmilioPelaez 的答案都与这张原始海报在the Swift forum question 上给出的另一个答案相吻合。我接受这些答案,因为它们比 Swift 语言指南中给出的更好。但是@ChipJarred 有一个很好的观点。如果原因是因为编译器认为允许对全局变量进行这种访问风险太大,那么为什么编译器不认为以类似方式访问其他全局对象有风险呢?我同意这似乎不一致。
【解决方案3】:

Andrew_TrickSwift Forums 上的回答:

“不要互动”是一个强有力的声明。编译器只是检查在调用“balance”中对“oscar”的每次访问只能修改独立的内存块(“heath”与“energy”)。这是一种特殊情况,因为对结构的任何访问通常都被建模为对整个结构值的读/写。编译器会做一些额外的工作来检测并允许这种特殊情况,因为在这种情况下复制“oscar”结构会很不方便。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2016-02-08
    • 1970-01-01
    相关资源
    最近更新 更多