Почему функция имеет долгосрочный доступ для записи ко всем своим входным и выходным параметрам?

Согласно главе «Безопасность памяти» в Руководстве по языку программирования Swift (для Swift 4.2) есть предложение «Функция имеет долгосрочный доступ для записи ко всем своим входным и выходным параметрам». https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html

Я создал новый проект инструмента командной строки, чтобы проверить его в Xcode 10.1.

var stepSize = 1

func increment(_ number: inout Int) {
  print(stepSize)
}

increment(&stepSize)

Я ожидаю, что на выходе будет 1, но на самом деле это журнал сбоев «Одновременный доступ к 0x100587430, но для модификации требуется монопольный доступ».

Я знаю, что это конфликт из-за доступа к параметрам ввода-вывода, но я не знаю, почему это происходит. Почему функция имеет долгосрочный доступ для записи ко всем своим входным и выходным параметрам?


person Shawn 736    schedule 28.01.2019    source источник
comment
Доступ для записи для входного-выходного параметра [...] длится в течение всего времени вызова этой функции Вы говорите, что ожидаете, что доступ для записи закончится до возврата функции?   -  person jscs    schedule 28.01.2019
comment
почему возникает конфликт памяти в одном потоке Swift? я никогда не слышал о конфликте памяти в javascript   -  person briefy    schedule 24.12.2020
comment
См. обсуждение проверки эксклюзивности памяти на WWDC 2018 Что нового в Swift.   -  person Rob    schedule 24.12.2020


Ответы (1)


Потребитель этого API видит func increment(_ number: inout Int), но не видит реализацию. Он может только предположить, что increment(_:) производит запись в параметры, потому что может, в принципе.

Даже если реализация функции в настоящее время не выполняет никаких операций записи, такая возможность существует, поэтому компилятору приходится исходить из наихудшего сценария. Представьте, если бы какой-то клиентский код был разрешен для компиляции с этим, обрабатывая его так, как если бы он был только для чтения (потому что в то время это могло быть так). Что должно произойти с клиентским кодом, когда кто-то добавит number += 1 в тело функции?

Это похоже на функцию, которая объявляет, что может throw, а фактическая реализация не throw. Компилятор по-прежнему считает это броском и требует обработки ошибки с помощью некоторого варианта try.

person Alexander    schedule 28.01.2019