小编chu*_*uck的帖子

在 Rust 中左移 (<<) 时如何惯用地测试溢出?

对于大多数可能溢出的操作符,Rust 提供了一个检查版本。例如,要测试加法是否溢出,可以使用checked_add

match 255u8.checked_add(1) {
    Some(_) => println!("no overflow"),
    None => println!("overflow!"),
}
Run Code Online (Sandbox Code Playgroud)

这打印"overflow!". 还有一个checked_shl, 但根据文档,它只检查移位是否大于或等于self. 这意味着虽然这个:

match 255u8.checked_shl(8) {
    Some(val) => println!("{}", val),
    None => println!("overflow!"),
}
Run Code Online (Sandbox Code Playgroud)

被捕获并打印"overflow!",这是:

match 255u8.checked_shl(7) {
    Some(val) => println!("{}", val),
    None => println!("overflow!"),
}
Run Code Online (Sandbox Code Playgroud)

只是打印128,显然没有捕捉到溢出。向左移动时检查任何类型溢出的正确方法是什么?

integer-overflow bit-shift logical-operators rust

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

为什么 Rust 堆栈框架如此之大?

我遇到了意外的早期堆栈溢出并创建了以下程序来测试该问题:

#![feature(asm)]
#[inline(never)]
fn get_rsp() -> usize {
    let rsp: usize;
    unsafe {
        asm! {
            "mov {}, rsp",
            out(reg) rsp
        }
    }
    rsp
}

fn useless_function(x: usize) {
    if x > 0 {
        println!("{:x}", get_rsp());
        useless_function(x - 1);
    }
}

fn main() {
    useless_function(10);
}
Run Code Online (Sandbox Code Playgroud)

这是get_rsp反汇编的(根据cargo-asm):

tests::get_rsp:
 push    rax
 #APP
 mov     rax, rsp
 #NO_APP
 pop     rcx
 ret
Run Code Online (Sandbox Code Playgroud)

我不确定什么#APP#NO_APP做什么或为什么rax被压入然后弹出rcx,但似乎该函数确实返回了堆栈指针。

我很惊讶地发现在调试模式下,两个连续打印之间的差异rsp是 192(!),甚至在发布模式下也是 128。据我所知,每次调用需要存储的useless_function只是一个usize和一个返回地址,所以我希望每个堆栈帧大约 16 …

stack-overflow x86-64 inline-assembly rust

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

如何使用嵌入切片创建指向未调整大小类型的智能指针?

我试图通过使用像 C 的灵活数组成员这样的东西来避免多个堆分配。为此,我需要分配一个未定义大小的结构,但我没有找到任何通过智能指针来实现的方法。我对 尤其感兴趣Rc,但这也是 的情况Box,所以这就是我将在示例中使用的内容。

这是我迄今为止最接近的:

use std::alloc::{self, Layout};

struct Inner {/* Sized fields */}

#[repr(C)] // Ensure the array is always last
// Both `inner` and `arr` need to be allocated, but preferably not separately
struct Unsized {
    inner: Inner,
    arr: [usize],
}

pub struct Exposed(Box<Unsized>);

impl Exposed {
    pub fn new(capacity: usize) -> Self {
        // Create a layout of an `Inner` followed by the array
        let (layout, arr_base) = Layout::array::<usize>(capacity)
            .and_then(|arr_layout| Layout::new::<Inner>().extend(arr_layout))
            .unwrap(); …
Run Code Online (Sandbox Code Playgroud)

smart-pointers rust

4
推荐指数
1
解决办法
245
查看次数