Ожидается ли, что слишком большое битовое смещение - неопределенное поведение в Rust?
Когда вы запускаете этот код:
#![allow(exceeding_bitshifts)]
fn main() {
const NUMBER: u64 = 0b_10101010;
fn print_shift(i: u32) {
println!("{:b}", NUMBER >> i);
}
print_shift(65);
println!("{:b}", NUMBER >> 65);
}
Вы видите, что смещение битов числа со значением, которое превышает длину в битах, приводит к другому поведению при выполнении во время компиляции или во время выполнения.
Это нормальное поведение? Это где-то задокументировано? Этого нет в списке задокументированных неопределенных действий.
1 ответ
Нет, это не ожидается, но это не неопределенное поведение. Это просто ошибка.
Не должно быть никакой разницы между тем, как константа вычисляется во время компиляции, и тем, как значение вычисляется во время выполнения. В общем, это сложная проблема, поскольку машина, выполняющая компиляцию, и машина, выполняющая код, могут иметь совершенно разные архитектуры.
Когда речь идет о сборках отладки и выпуска, ожидается поведение "слишком больших" сдвигов битов, которое также не является неопределенным поведением. Подсказка в сообщении об ошибке:
попытка сдвига вправо с переполнением
Целочисленное переполнение не является ни небезопасным, ни неопределенным:
Компилятор Rust не считает следующие поведения небезопасными, хотя программист может (должен) счесть их нежелательными, неожиданными или ошибочными.
- ...
- Целочисленное переполнение
Смотрите также: