Напрямую назначать UnsafePointer - PullRequest
0 голосов
/ 20 сентября 2018

Может кто-нибудь объяснить мне, что мне здесь не хватает?

Учитывая

let index: Int32 = 100

Почему это не так:

// Use of extraneous '&'
let ptr = &index // Type inference?

Или даже:

// Use of extraneous '&'
let ptr: UnsafePointer<Int32> = &index

Но это:

{
    func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
        return num
    }
    let ptr = point(num: &index)
}

Это будет простой эквивалент этого в C:

int index = 100;
int *ptr = &index;

Нужно ли мне действительно определять функциючто буквально принимает ссылочное значение и возвращает ту же самую ссылку?Что-то не так в этом.Похоже, что я что-то здесь упускаю, может быть, даже фундаментальный.

Как назначить UnsafePointer для адреса памяти того типа, которым он является (в данном случае Int32) ???

Спасибо!

Редактировать:

В конечном итоге я пытаюсь выполнить несколько различных структур в двоичном файле.Переменная index будет свойством структуры.Путь, по которому я сейчас иду, включает файл OutputStream.Я не против получить предложения по этому вопросу, но выходит за рамки первоначального вопроса.

1 Ответ

0 голосов
/ 20 сентября 2018

Я не знаю точного обоснования, но предположительно let ptr = &index не разрешено, потому что нет никакой гарантии, что вы можете разыменовать ptr, не вызывая неопределенное поведение (при условии, что index неглобальная или static хранимая переменная - единственные случаи, когда Swift гарантирует стабильные и уникальные значения указателя.

В отличие от других языков, Swift не гарантирует, что локальная переменная останется инициализированной до конца области видимости.он объявлен в - оптимизатор может деинициализировать его раньше.Поэтому, допустив let ptr = &index, можно было бы слишком легко писать неправильный код.

Стоит отметить, что ваш пример:

func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
    return num
}
let ptr = point(num: &index)

также неэффективен.Попытка разыменования ptr из let ptr = point(num: &index) является неопределенным поведением, поскольку преобразование аргумента inout-to-pointer создает временный указатель, действительный только на время вызова функции.

Если вы хотите scoped временный указатель на значение, вы можете использовать withUnsafePointer(to:) - например:

func baz() {
  var foo = 5
  withUnsafePointer(to: &foo) { ptr in
    // use `ptr` here – do not escape it!
  }

  // In Swift 4.2 you can also use `withUnsafePointer(to:)` on let constants.
  let bar = 5
  withUnsafePointer(to: bar) { ptr in
    // use `ptr` here – do not escape it!
  }
}

Обратите внимание, что указатель действителен только на время закрытия - попыткавыход из него приведет к неопределенному поведению.

...