2015-04-25 3 views
1

Я пытаюсь запустить эту ржавчину кодсбоя при попытке сделать сдвиг битого

use std::net::Ipv4Addr; 

fn ip_to_int(addr: Ipv4Addr) -> u32 { 
     let ip = addr.octets(); 
     (ip[0] as u32) << 24 + (ip[1] as u32) << 16 + (ip[2] as u32) << 8 + (ip[3] as u32) 
    } 

fn main() { 
    let ip = Ipv4Addr::new(74, 125, 227, 0); 
    println!("{}", ip_to_int(ip)); 
} 

Это падает с

thread '<main>' panicked at 'shift operation overflowed', test.rs:5 

Я типажом все для 32-битных целых чисел и сдвига не больше, чем 32 биты. Почему он падает? Кроме того, не компилятор должен поймать это и предотвратить компиляцию?

[email protected]:~$ rustc --version 
rustc 1.1.0-nightly (21f278a68 2015-04-23) (built 2015-04-24) 
+1

Переполнение говорит арифметическое переполнение, то есть. что бит был потерян. Учитывая, что 'ip' является' [u8; 4] ', никакая часть этого выражения не должна вызывать переполнение. –

ответ

6

Согласно the Rust reference, оператор + как более сильное, чем приоритет оператора <<, а это означает, что ваше выражение фактически анализируется так:

(ip[0] as u32) << (24 + (ip[1] as u32)) << (16 + (ip[2] as u32)) << (8 + (ip[3] as u32)) 

Который может довольно легко переполнения.

Вы должны добавить усваивает скобки:

((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32) 
+0

Спасибо, это сработало как шарм! –

Смежные вопросы