我的理解是,由于称为"严格别名规则",以下代码在C++中具有未定义的行为.
#include <cstdint>
enum Foo : int16_t {};
void test(Foo& foo) {
reinterpret_cast<int16_t&>(foo) = 42;
}
Run Code Online (Sandbox Code Playgroud)
特别是,C++编译器可以完全省略赋值,因为允许它假设int16_t&由(它们的类型)不同而reinterpret_cast不是指向与foo(类型Foo&)相同的内存.
我的问题是,Rust是否有类似于C++"严格别名规则"的东西?换句话说,下面的等效Rust代码是否有未定义的行为?
#[repr(i16)]
enum Foo { Dummy }
unsafe fn test(foo: &mut Foo) {
*std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
上面的Rust示例代码中存在一个不相关的问题,即test创建一个不存在的枚举变体.所以,这里有相同的代码快速修复:
#[repr(i16)]
enum Foo { Dummy, Yummy = 42 }
unsafe fn test(foo: &mut Foo) {
*std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}
Run Code Online (Sandbox Code Playgroud) 我需要将数组的每个元素初始化为非常量表达式.我是否可以这样做而无需先将数组的每个元素初始化为一些无意义的表达式?以下是我希望能够做到的一个例子:
fn foo(xs: &[i32; 1000]) {
let mut ys: [i32; 1000];
for (x, y) in xs.iter().zip(ys.iter_mut()) {
*y = *x / 3;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
此代码给出了编译时错误:
error[E0381]: borrow of possibly uninitialized variable: `ys`
--> src/lib.rs:4:33
|
4 | for (x, y) in xs.iter().zip(ys.iter_mut()) {
| ^^ use of possibly uninitialized `ys`
Run Code Online (Sandbox Code Playgroud)
要解决这个问题,我需要更改函数的第一行,ys用一些虚拟值初始化元素,如下所示:
let mut ys: [i32; 1000] = [0; 1000];
Run Code Online (Sandbox Code Playgroud)
有没有办法省略额外的初始化?将所有内容包装在unsafe块中似乎没有任何区别.
您将如何创建一个堆栈分配的类似矢量的容器,它可以包含的元素数量有一些固定的上限?您可以在下面看到我的尝试,但它无法编译:
// The following is at crate level
#![feature(unsafe_destructor)]
use std::mem;
use std::ptr;
use std::slice::Iter;
pub struct StackVec<T> {
buf: [T; 10],
len: usize,
}
impl<T> StackVec<T> {
pub fn new() -> StackVec<T> {
StackVec {
buf: unsafe { mem::uninitialized() },
len: 0,
}
}
pub fn iter(&self) -> Iter<T> {
(&self.buf[..self.len]).iter()
}
pub fn push(&mut self, value: T) {
unsafe { ptr::write(self.buf.get_mut(self.len).unwrap(), value); }
self.len += 1;
}
pub fn pop(&mut self) -> Option<T> {
if self.len == 0 …Run Code Online (Sandbox Code Playgroud) 为什么代码示例1编译但示例2给出了编译错误?
例1:
use std::ops::Index;
struct Bounded {
idx: usize,
}
impl Index<Bounded> for [i32; 4] {
type Output = i32;
fn index(&self, b: Bounded) -> &i32 {
unsafe { self.get_unchecked(b.idx) }
}
}
Run Code Online (Sandbox Code Playgroud)
例2:
use std::ops::Index;
struct Bounded {
idx: usize,
}
impl<T> Index<Bounded> for [T; 4] {
type Output = T;
fn index(&self, b: Bounded) -> &T {
unsafe { self.get_unchecked(b.idx) }
}
}
Run Code Online (Sandbox Code Playgroud)
error[E0210]: type parameter `T` must be used as the type parameter for some local type …Run Code Online (Sandbox Code Playgroud)