"struct field is never used",但 RAII 需要
"struct field is never used", but needed by RAII
我正在尝试通过以某种 RAII 样式组合 os::MemoryMap
和 fs::File
来实现内存映射文件。考虑以下示例:
#![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() });
}
有效,但编译器将 Mmapped 对象中的 file 字段视为无效代码:
<anon>:13:5: 13:15 warning: struct field is never used: `file`, #[warn(dead_code)] on by default
<anon>:13 file: File,
^~~~~~~~~~
我可以确定它不会优化它,并且文件将在 new 方法中关闭吗?是否有任何标准方法来标记我的字段 "not dead" 代码?
您可以注释特定字段以忽略死代码警告:
struct Mmapped {
#[allow(dead_code)]
file: File,
map: MemoryMap,
map_len: usize,
}
我不相信优化器会从结构中完全删除该字段,并且快速查看具有未使用的字符串字段的结构的 LLVM IR 表明仍然有 space该字段,甚至调用该字符串的滴胶。
我认为惯用的方法是在字段名称前加上 _
,这也会消除警告:
struct Mmapped {
_file: File,
map: MemoryMap,
map_len: usize,
}
我确实在标准库代码中注意到了这种模式。
我正在尝试通过以某种 RAII 样式组合 os::MemoryMap
和 fs::File
来实现内存映射文件。考虑以下示例:
#![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() });
}
有效,但编译器将 Mmapped 对象中的 file 字段视为无效代码:
<anon>:13:5: 13:15 warning: struct field is never used: `file`, #[warn(dead_code)] on by default
<anon>:13 file: File,
^~~~~~~~~~
我可以确定它不会优化它,并且文件将在 new 方法中关闭吗?是否有任何标准方法来标记我的字段 "not dead" 代码?
您可以注释特定字段以忽略死代码警告:
struct Mmapped {
#[allow(dead_code)]
file: File,
map: MemoryMap,
map_len: usize,
}
我不相信优化器会从结构中完全删除该字段,并且快速查看具有未使用的字符串字段的结构的 LLVM IR 表明仍然有 space该字段,甚至调用该字符串的滴胶。
我认为惯用的方法是在字段名称前加上 _
,这也会消除警告:
struct Mmapped {
_file: File,
map: MemoryMap,
map_len: usize,
}
我确实在标准库代码中注意到了这种模式。