小编kmk*_*mky的帖子

Rust严格别名?

我的理解是,由于称为"严格别名规则",以下代码在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)

strict-aliasing undefined-behavior rust

11
推荐指数
1
解决办法
898
查看次数

有没有办法不必两次初始化数组?

我需要将数组的每个元素初始化为非常量表达式.我是否可以这样做而无需先将数组的每个元素初始化为一些无意义的表达式?以下是我希望能够做到的一个例子:

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块中似乎没有任何区别.

arrays initialization array-initialization rust

10
推荐指数
1
解决办法
1478
查看次数

如何创建堆栈分配的矢量类容器?

您将如何创建一个堆栈分配的类似矢量的容器,它可以包含的元素数量有一些固定的上限?您可以在下面看到我的尝试,但它无法编译:

// 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)

stack vector rust

7
推荐指数
1
解决办法
1936
查看次数

为什么一致性规则会引发错误"类型参数必须用作某些本地类型的类型参数"?

为什么代码示例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)

rust

5
推荐指数
1
解决办法
381
查看次数

为什么Rust的排序方法会分配内存?

sort_byon std::slice::MutableSliceAllocatingsort_byon 这样的方法collections::vec::Vec被记录为"分配大约2*n,其中n是长度".我不认为好的C++ std::sort实现(在堆上)分配,但它们实现了相同的O(n log n)复杂性.虽然,与C++ std :: sort不同,Rust排序方法是稳定的.

为什么Rust排序方法分配?对我来说,它不符合这里宣传的"零成本抽象"法案.

sorting dynamic-allocation rust

2
推荐指数
2
解决办法
791
查看次数