Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Пример: функция may_overflow

// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

/// Прибавляет 2^31 - 1 к отрицательным числам без проверки переполнения.
///
/// # Safety
///
/// Вызов с `a >= 1` приводит к переполнению знакового целого, что является
/// неопределённым поведением при использовании `unchecked_add`.
unsafe fn may_overflow(a: i32) -> i32 {
    unsafe { a.unchecked_add(i32::MAX) }
}

fn main() {
    let x = unsafe { may_overflow(123) };
    println!("{x}");
}
This slide should take about 10 minutes.

«Ключевое слово unsafe может иметь немного иной смысл, чем предполагают некоторые».

«Автор кода считает, что код корректен. В принципе, код безопасен».

«В этом игрушечном примере функция may_overflow предназначена для вызова только с отрицательными числами».

Спросите слушателей, могут ли они объяснить, почему may_overflow требует ключевого слова unsafe.

«Если вы не уверены, в чём проблема, давайте ненадолго остановимся и объясним. Для положительных чисел в i32 доступно только 31 бит».

В стандартном безопасном Rust переполнение целого (например, a + i32::MAX) не является неопределённым поведением: при включённых проверках переполнения (отладочная сборка) программа паникует, а в релизной сборке выполняется перенос в дополнительном коде. Однако unchecked_add — небезопасная операция, которая полностью пропускает проверки переполнения и объявляет переполнение неопределённым поведением (UB). Компиляторы оптимизируют код, исходя из того, что неопределённое поведение невозможно, и это может привести к удалению «мёртвого» кода и неожиданному поведению во время выполнения.

Скомпилируйте и запустите код: в отладочной сборке стандартная библиотека обнаруживает нарушение предусловия безопасности и паникует (unsafe precondition(s) violated: i32::unchecked_add cannot overflow). В релизной сборке unchecked_add порождает настоящее UB.

«Этот код можно использовать корректно, однако неправильное использование крайне опасно».

«А компилятор не может проверить, что использование корректно».

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