为什么有必要对一行中的可变原始指针执行两次转换?

时间:2016-01-09 08:17:54

标签: pointers casting rust

在查看unix-socket时,我发现了这段代码:

let timeout = unsafe {
    let mut timeout: libc::timeval = mem::zeroed();
    let mut size = mem::size_of::<libc::timeval>() as libc::socklen_t;
    try!(cvt(libc::getsockopt(self.0,
                              libc::SOL_SOCKET,
                              kind,
                              &mut timeout as *mut _ as *mut _,
                              &mut size as *mut _ as *mut _)));
    timeout
};

我特别好奇这些界限:

&mut timeout as *mut _ as *mut _,
&mut size as *mut _ as *mut _

为什么有必要对一行中的可变原始指针执行两次转换?为什么仅仅施放一次就不够了?

1 个答案:

答案 0 :(得分:9)

timeout例如对应*mut c_void参数:

pub unsafe extern fn getsockopt(sockfd: c_int, level: c_int, optname: c_int,
                                optval: *mut c_void, optlen: *mut socklen_t) -> c_int

该文件中的timeout定义为:

let mut timeout: libc::timeval = mem::zeroed();

所以类型为libc::timeval。现在让我们考虑一下:

&mut timeout as *mut _ as *mut _

首先,您有&mut timeout,因此类型为&mut libc::timeval。然后你执行as *mut _将它强制转换为推断类型的原始可变指针,在这种情况下它是libc::timeval的相同类型,所以到目前为止的完整类型是:*mut libc::timeval,与参数类型*mut c_void不匹配。最后的as *mut _再次推断出目标类型,现在是参数类型*mut c_void,因此最终会将*mut libc::timeval强制转换为*mut c_void