Материал проходит вычитку — возможны неточности.
Урок 40 из 118

Границы указателей †

Во время аудита Миша наткнулся на старую часть проекта: связку с C-библиотекой разбора форматов. «Работает — не трогаем, — решил Сергей. — Здесь язык не защищает, здесь граница».

Главная мысль

в Go нет арифметики указателей — это осознанное ограничение ради безопасности и совместимости со сборщиком мусора; редкие места, где она нужна, покрывает unsafe.

В Go нет арифметики указателей. Нельзя написать p + 1, чтобы пройти к следующему элементу, нельзя перескакивать по памяти произвольными шагами, нельзя кастить указатель на структуру в указатель на число.

Что не скомпилируется

p := &size
p + 1        // ошибка компиляции
*p + 1       // а вот это работает: прибавили к значению, а не к адресу

Разница между p + 1 и *p + 1 — ровно та же, что между &x и *p из прошлого урока: первое — про адрес, второе — про значение. Адресную арифметику язык не даёт.

Почему ограничение и где его обходят

Это осознанное решение: арифметика указателей — источник целого класса багов, от переполнения буфера до несовместимости со сборщиком мусора, которому нужно точно знать, где в памяти лежат указатели.

Для тех редких мест, где арифметика реально нужна — связь с C через cgo, некоторые системные вызовы — есть unsafe.Pointer и uintptr. Именно так устроена старая часть «Полки», работающая с C-библиотекой. Но они на то и unsafe: компилятор и рантайм снимают с себя гарантии безопасности, как только ты туда лезешь. Имя пакета — предупреждение, а не название.

В следующем уроке

Вы узнаете:

  • как Go-код через cgo вызывает C и почему там unsafe.Pointer
  • как GC размечает указатели и почему произвольные адреса ему мешают
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

p := &size. Что произойдёт при p + 1?

Вопрос 2 из 3

Зачем сборщику мусора точно знать, где в памяти лежат указатели?

Вопрос 3 из 3

Какие гарантии снимает с себя unsafe при использовании unsafe.Pointer и uintptr?

Итоги

Указатели в Go — «безопасные»: ни арифметики, ни произвольных приведений. Нужно что-то низкоуровневое — unsafe, но с пониманием, что гарантии языка отключаются.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки