"结构字段永远不会被使用",但RAII需要它

swi*_*ard 2 raii rust

我试图通过组合os::MemoryMapfs::File某种RAII样式来实现内存映射文件.请考虑以下示例:

#![feature(fs, os, io, path, std_misc, core)]

use std::{io, os, mem, raw};
use std::io::{Seek};
use std::fs::{File};
use std::path::{Path};
use std::os::{MemoryMap};
use std::borrow::{Cow};
use std::error::{FromError};
use std::os::unix::{AsRawFd};

struct Mmapped {
    file: File,
    map: MemoryMap,
    map_len: usize,
}

#[derive(Debug)]
enum Error {
    IoError(io::Error),
    MmapError(os::MapError),
}

impl FromError<io::Error> for Error { 
    fn from_error(err: io::Error) -> Error { Error::IoError(err) }
}

impl FromError<os::MapError> for Error { 
    fn from_error(err: os::MapError) -> Error { Error::MmapError(err) }
}

impl Mmapped {
    fn new(filename: &str) -> Result<Mmapped, Error> {
        let mut file = try!(File::open(Path::new(filename)));
        let map_len = try!(file.seek(io::SeekFrom::End(0))) as usize;
        let map = try!(MemoryMap::new(map_len, &[os::MapOption::MapReadable, os::MapOption::MapFd(file.as_raw_fd())]));
        Ok(Mmapped { file: file, map: map, map_len: map_len })
    }

    unsafe fn as_string<'a>(&self) -> Cow<'a, String, str> {
        String::from_utf8_lossy(mem::transmute(raw::Slice { data: self.map.data() as *const u8, 
                                                            len: self.map_len }))
    }
}

fn main() {
    let m = Mmapped::new("test.txt").unwrap();
    println!("File contents: {:?}", unsafe { m.as_string() });
}
Run Code Online (Sandbox Code Playgroud)

围栏

它可以工作,但编译器将Mmapped对象中的文件字段视为死代码:

<anon>:13:5: 13:15 warning: struct field is never used: `file`, #[warn(dead_code)] on by default
<anon>:13     file: File,
              ^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我可以确定它不会优化它,文件将以方法关闭吗?是否有任何标准方法来标记我的字段"未死"代码?

Vla*_*eev 11

我认为惯用的方法是在字段名称前加上_,这也会使警告静音:

struct Mmapped {
    _file: File,
    map: MemoryMap,
    map_len: usize,
}
Run Code Online (Sandbox Code Playgroud)

我肯定在标准库代码中注意到了这种模式.


She*_*ter 6

您可以注释特定字段以忽略死代码警告:

struct Mmapped {
    #[allow(dead_code)]
    file: File,
    map: MemoryMap,
    map_len: usize,
}
Run Code Online (Sandbox Code Playgroud)

我不相信优化器会完全从结构中删除该字段,并且快速查看具有未使用的 String 字段的结构的 LLVM IR 显示该字段仍然有空间,甚至调用删除胶水那个字符串。