воскресенье, 23 июня 2019 г.

Спецификация Go: системные замечания, пакет unsafe

Встроенный пакет unsafe, известный компилятору и доступный по пути импорта "unsafe", предоставляет средства для низкоуровневого программирования, включая операции, которые нарушают систему типов. Пакет, использующий unsafe, должен быть проверен вручную для безопасности типа и не может быть переносимым. Пакет предоставляет следующий интерфейс:

package unsafe

// сокращение для произвольного типа Go; 
// это не настоящий тип
type ArbitraryType int  

type Pointer *ArbitraryType

func Alignof(variable ArbitraryType) uintptr
func Offsetof(selector ArbitraryType) uintptr
func Sizeof(variable ArbitraryType) uintptr

Pointer является типом указателя, но значение Pointer не может быть разыменовано. Любой указатель или значение базового типа uintptr может быть преобразовано в тип базового типа Pointer и наоборот. Эффект преобразования между Pointer и uintptr определяется реализацией.

var f float64
bits = *(*uint64)(unsafe.Pointer(&f))

type ptr unsafe.Pointer
bits = *(*uint64)(ptr(&f))

var p ptr = nil

Функции Alignof и Sizeof принимают выражение x любого типа и возвращают выравнивание или размер, соответственно, гипотетической переменной v, как если бы v было объявлено через var v = x.

Функция Offsetof принимает (возможно заключенный в скобки) селектор s.f, обозначающий поле f структуры, обозначенной s или *s, и возвращает смещение поля в байтах относительно адреса структуры. Если f является встроенным полем, оно должно быть доступно без косвенных указателей через поля структуры. Для структуры s с полем f:

uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))

Компьютерные архитектуры могут требовать выравнивания адресов памяти; то есть, чтобы адреса переменной были кратны фактору, выравнивание типа переменной. Функция Alignof принимает выражение, обозначающее переменную любого типа, и возвращает выравнивание (тип) переменной в байтах. Для переменной x:

uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0

Вызовы Alignof, Offsetof и Sizeof являются константными выражениями времени компиляции типа uintptr.

Размер и гарантия выравнивания

Для числовых типов гарантируются следующие размеры:

тип                                 размер в байтах

byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16

Следующие минимальные свойства выравнивания гарантированы:

  1. Для переменной x любого типа: unsafe.Alignof(x) по крайней мере 1.
  2. Для переменной x типа struct: unsafe.Alignof(x) является наибольшим из всех значений unsafe.Alignof(x.f) для каждого поля f из x, но не менее 1.
  3. Для переменной x типа массива: unsafe.Alignof(x) совпадает с выравниванием переменной типа элемента массива.

Тип структуры или массива имеет нулевой размер, если он не содержит полей (или элементов соответственно), размер которых больше нуля. Две разные переменные нулевого размера могут иметь один и тот же адрес в памяти.


Читайте также:


Комментариев нет:

Отправить комментарий