💡 Инструкция: Выберите один ответ из пяти. На 30 вопросов отведено 85 минут. В каждом вопросе верен только один вариант. После завершения вы увидите общий результат, результаты по 6 тематическим шкалам и подробные объяснения.
Вопрос 22 из 30
Чем завершится выполнение фрагмента с `std::slice::from_raw_parts_mut`?
Rust Rust · Безопасная оболочка Копировать
pub fn split_at_mut<T>(slice: &mut [T], mid: usize) -> (&mut [T], &mut [T]) {
assert!(mid <= slice.len());
let ptr = slice.as_mut_ptr();
unsafe {
(std::slice::from_raw_parts_mut(ptr, mid),
std::slice::from_raw_parts_mut(ptr.add(mid), slice.len() - mid))
}
}
Код компилируется, но miri автоматически исправляет нарушение aliasing и продолжает тест. Из этого следовало бы, что иной порядок операций для `split_at_mut` ничего не меняет.
Компиляция закончится диагностикой: `extern`-блок редакции 2024 помечен unsafe. До последней строки и наблюдаемого результата программа при таком разборе не доходит. По этой логике отдельная проверка `split_at_mut` на другом входе считалась бы лишней.
До выполнения код дойдёт без ошибки компиляции, поскольку `unsafe`-блок проверяет валидность указателя перед разыменованием.
Оболочка безопасна при доказанных условиях: обе части находятся в одном выделении, имеют корректные длины и не пересекаются.
До выполнения код дойдёт без ошибки компиляции, поскольку miri подтверждает отсутствие UB во всех неисполненных ветвях. Из этого следовало бы, что иной порядок операций для `split_at_mut` ничего не меняет.
Вопрос 26 из 30
Какой рефакторинг исправляет причину сбоя возле `std::slice::from_raw_parts_mut`?
Rust Rust · Безопасная оболочка Копировать
pub fn split_at_mut<T>(slice: &mut [T], mid: usize) -> (&mut [T], &mut [T]) {
assert!(mid <= slice.len());
let ptr = slice.as_mut_ptr();
unsafe {
(std::slice::from_raw_parts_mut(ptr, mid),
std::slice::from_raw_parts_mut(ptr.add(mid), slice.len() - mid))
}
}
Использовать `transmute` для данных рядом с `split_at_mut`, не проверяя размер, выравнивание и допустимые значения.
Расширить `unsafe`-блок вокруг `split_at_mut` до всей функции, оставив инварианты данные этого фрагмента неоформленными.
Считать layout вокруг `split_at_mut` на текущей цели стабильным ABI-контрактом и удалить явные проверки границы «Безопасная оболочка».
Подавить сообщение Miri или санитайзера для `split_at_mut`, если обычный тест не воспроизводит сбой. Сигнатура при этом почти не меняется, однако исходное предусловие остаётся скрытым.
Проверить mid до unsafe, вычислить части один раз и не сохранять исходную &mut ссылку для доступа; описать доказательство непересечения рядом с блоком.
Вопрос 29 из 30
Как следует интерпретировать результат проверки `&mut`?
Rust Rust · Безопасная оболочка Копировать
let mut data = [1, 2, 3, 4];
let (a, b) = split_at_mut(&mut data, 2);
a[0] = 9; b[0] = 8;
assert_eq!(data, [9, 2, 8, 4]);
Тест подтверждает обычный результат и независимость частей, но не заменяет доказательство отсутствия перекрытия для всех mid.
Раз тест прошёл, производительность решения тоже можно считать подтверждённой. Из этого следовало бы, что иной порядок операций для `assert_eq!` ничего не меняет.
Если сценарий проходит в debug-сборке, в release и на другой целевой платформе результат будет тем же. Такое рассуждение переносило бы вывод о `assert_eq!` на неисполненную ветвь.
Успешного основного сценария достаточно; отмену, частичное завершение и повторный вход отдельно проверять не нужно. Из этого следовало бы, что иной порядок операций для `assert_eq!` ничего не меняет.
Успешный запуск подтверждает корректность не только этого пути, но и остальных ветвей программы.