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

Вызов небезопасных функций

Несоблюдение требований безопасности нарушает безопасность памяти!

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

#[derive(Debug)]
#[repr(C)]
struct KeyPair {
    pk: [u16; 4], // 8 байт
    sk: [u16; 4], // 8 байт
}

const PK_BYTE_LEN: usize = 8;

fn log_public_key(pk_ptr: *const u16) {
    let pk: &[u16] = unsafe { std::slice::from_raw_parts(pk_ptr, PK_BYTE_LEN) };
    println!("{pk:?}");
}

fn main() {
    let key_pair = KeyPair { pk: [1, 2, 3, 4], sk: [0, 0, 42, 0] };
    log_public_key(key_pair.pk.as_ptr());
}

Всегда добавляйте комментарий о безопасности (// SAFETY:) к каждому блоку unsafe. Он должен объяснять, почему код действительно безопасен. В этом примере комментарий о безопасности отсутствует, и код некорректен.

Ключевые моменты:

  • Второй аргумент slice::from_raw_parts — это количество элементов, а не байтов! В этом примере демонстрируется неожиданное поведение: чтение за пределами одного массива и попадание в другой.
  • Это неопределённое поведение, потому что мы читаем за пределами массива, из которого был получен указатель.
  • log_public_key должна быть unsafe, потому что pk_ptr должен удовлетворять определённым предусловиям, чтобы избежать неопределённого поведения. Безопасную функцию, которая может вызвать неопределённое поведение, называют unsound (некорректной). Что должна говорить её документация о безопасности?
  • В стандартной библиотеке есть ряд низкоуровневых небезопасных функций. По возможности предпочитайте безопасные альтернативы!
  • Если вы используете небезопасную функцию как оптимизацию, обязательно добавьте бенчмарк, чтобы продемонстрировать выигрыш.