小编Luk*_*odt的帖子

为什么clang用-O0生成效率低的asm(对于这个简单的浮点和)?

我在llvm clang Apple LLVM 8.0.0版(clang-800.0.42.1)上反汇编代码:

int main() {
    float a=0.151234;
    float b=0.2;
    float c=a+b;
    printf("%f", c);
}
Run Code Online (Sandbox Code Playgroud)

我编译时没有-O规范,但我也试过-O0(给出相同)和-O2(实际上计算值并存储它预先计算)

产生的反汇编如下(我删除了不相关的部分)

->  0x100000f30 <+0>:  pushq  %rbp
    0x100000f31 <+1>:  movq   %rsp, %rbp
    0x100000f34 <+4>:  subq   $0x10, %rsp
    0x100000f38 <+8>:  leaq   0x6d(%rip), %rdi       
    0x100000f3f <+15>: movss  0x5d(%rip), %xmm0           
    0x100000f47 <+23>: movss  0x59(%rip), %xmm1        
    0x100000f4f <+31>: movss  %xmm1, -0x4(%rbp)  
    0x100000f54 <+36>: movss  %xmm0, -0x8(%rbp)
    0x100000f59 <+41>: movss  -0x4(%rbp), %xmm0         
    0x100000f5e <+46>: addss  -0x8(%rbp), %xmm0
    0x100000f63 <+51>: movss  %xmm0, -0xc(%rbp)
    ...
Run Code Online (Sandbox Code Playgroud)

显然它正在做以下事情:

  1. 将两个浮点数加载到寄存器xmm0和xmm1上
  2. 把它们放在堆栈中
  3. 从堆栈加载一个值(不是之前的xmm0)到xmm0
  4. 执行添加. …

c assembly x86-64 compiler-optimization llvm-codegen

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

在声明性宏中构建所有元素对(二次集)

我有一个标识符列表,我想为该列表中的每对标识符调用一个宏.例如,如果我有a,b并且c,我想生成这个:

println!("{} <-> {}", a, a);
println!("{} <-> {}", a, b);
println!("{} <-> {}", a, c);
println!("{} <-> {}", b, a);
println!("{} <-> {}", b, b);
println!("{} <-> {}", b, c);
println!("{} <-> {}", c, a);
println!("{} <-> {}", c, b);
println!("{} <-> {}", c, c);
Run Code Online (Sandbox Code Playgroud)

当然,这是一个虚拟的例子.在我的真实代码中,标识符是类型,我想生成impl块或类似的东西.

我的目标是仅列出每个标识符一次.在我的实际代码中,我有大约12个标识符,并且不想手动写下所有12²= 144对.所以我认为宏可能会帮助我.我知道它可以通过所有强大的过程宏来解决,但我希望它也可以使用声明式宏(macro_rules!).


我尝试了我认为直观的处理方法(两个嵌套的"循环")(Playground):

macro_rules! print_all_pairs {
    ($($x:ident)*) => {
        $(
            $(
                println!("{} <-> {}", $x, $x);  // `$x, $x` feels awkward... …
Run Code Online (Sandbox Code Playgroud)

rust rust-macros rust-decl-macros

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

Why can't I import `std::assert` via `use` while it works for other macros from std?

With Rust 2018, this code works (Playground):

use std::panic;
use std::format;
use std::assert_eq;
Run Code Online (Sandbox Code Playgroud)

But this:

use std::assert;
Run Code Online (Sandbox Code Playgroud)

Results in this error:

error[E0432]: unresolved import `std::assert`
 --> src/lib.rs:4:5
  |
4 | use std::assert;
  |     ^^^^^^^^^^^ no `assert` in the root
Run Code Online (Sandbox Code Playgroud)

I read the edition guide about this topic and it says that use should work with macro_rules! macros and procedural macros. Thus, I'm confused.

macros rust

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

如何将字符串传递给HashSet包含?

我想使用HashSet快速字符串查找,但我似乎无法找到一种方法来传递字符串变量contains没有编译器错误.

refs = HashSet::new();

let first_pass = link_regex.replace_all(&buffer, |caps: &Captures| {

    if caps.len() == 2 {
        refs.insert(caps.at(2).unwrap());
    }

    caps.at(1).unwrap().to_owned()
});

let out = ref_regex.replace_all(&first_pass, |caps: &Captures| {
    let capture = caps.at(1).unwrap().to_owned();

    // only remove if we've seen it before
    if refs.contains(capture) {
        return "".to_string();
    }

    capture
});
Run Code Online (Sandbox Code Playgroud)

这会导致此错误:

 src/bin/remove_links.rs:30:26: 30:33 error: mismatched types [E0308]
 src/bin/remove_links.rs:30         if refs.contains(capture) {
                                                     ^~~~~~~
 src/bin/remove_links.rs:30:26: 30:33 help: run `rustc --explain E0308` to see a detailed explanation
 src/bin/remove_links.rs:30:26: 30:33 note: expected type …
Run Code Online (Sandbox Code Playgroud)

string hashset rust borrowing

3
推荐指数
1
解决办法
760
查看次数

以下代码段中的变量有什么价值?

fn main() {
    let data = &[1..3];
    println!("Data is {:?}", data);
}
Run Code Online (Sandbox Code Playgroud)

拥有&[1..3]此声明的指定值意味着什么?

rust

3
推荐指数
1
解决办法
74
查看次数

如何将结构的成员函数作为回调传递给另一个结构

我想将一个结构体的成员函数传递给另一个结构体。

对不起,英语不好,不能说更多细节。

use std::thread;

struct Struct1 {}

impl Struct1 {
    pub fn do_some(&mut self, s: &str) {
        // do something use s to modify self
    }
}

struct Struct2 {
    cb1: Box<Fn(&mut Struct1, &str)>,
}

fn main() {
    let s1 = Struct1 {};

    let s2 = Struct2 {
        cb1: Box::new(s1.do_some),  // how to store do_some function in cb1 ?
    };
}
Run Code Online (Sandbox Code Playgroud)

rust

3
推荐指数
1
解决办法
1691
查看次数

为什么生锈箱没有openssl-sys编译?

我刚刚在Rust项目中添加了一个外部包:

[dependencies]
feed = "2.0"
Run Code Online (Sandbox Code Playgroud)

这个箱子有几个依赖关系,特别是openssl-sys v0.9.10.当我尝试构建我的项目时,这个失败了:

$ cargo build 
Compiling unicode-normalization v0.1.4
Compiling openssl-probe v0.1.0
Compiling matches v0.1.4
Compiling log v0.3.7
Compiling unicode-bidi v0.2.5
Compiling libc v0.2.21
Compiling quick-xml v0.4.2
Compiling pkg-config v0.3.9
Compiling rss v0.4.0
Compiling idna v0.1.1
Compiling time v0.1.36
Compiling num-traits v0.1.37
Compiling gcc v0.3.45
Compiling num-integer v0.1.34
Compiling url v1.4.0
Compiling num-iter v0.1.33
Compiling num v0.1.37
Compiling chrono v0.3.0
Compiling openssl-sys v0.9.10
Compiling libz-sys v1.0.13
error: failed to run custom build command for …
Run Code Online (Sandbox Code Playgroud)

rust rust-cargo

3
推荐指数
1
解决办法
1343
查看次数

Cargo项目中的哪些文件应该在我的.gitignore中?

我创建了一个"hello world"Rust应用程序cargo new.当我执行git status它时显示了一堆文件:

A  rust/welcomec/Cargo.lock
A  rust/welcomec/Cargo.toml
A  rust/welcomec/src/main.rs
A  rust/welcomec/target/debug/.cargo-lock
A  rust/welcomec/target/debug/.fingerprint/welcomec-2d68725c8fae6fd1/bin-welcome-2d68725c8fae6fd1
A  rust/welcomec/target/debug/.fingerprint/welcomec-2d68725c8fae6fd1/bin-welcome-2d68725c8fae6fd1.json
A  rust/welcomec/target/debug/.fingerprint/welcomec-2d68725c8fae6fd1/dep-bin-welcome-2d68725c8fae6fd1
A  rust/welcomec/target/debug/deps/welcome-2d68725c8fae6fd1
A  rust/welcomec/target/debug/welcome
A  rust/welcomec/target/debug/welcome.d
Run Code Online (Sandbox Code Playgroud)

我可以安全地忽略这些文件和/或目录吗?

rust rust-cargo

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

为什么size_of :: <MyStruct>()不等于其字段大小的总和?

我试图测量结构及其字段(Playground)的大小:

use std::mem;

struct MyStruct {
    foo: u8,
    bar: char,
}

println!("MyStruct: {}", mem::size_of::<MyStruct>());

let obj = MyStruct { foo: 0, bar: '0' };
println!("obj:      {}", mem::size_of_val(&obj));
println!("obj.foo:  {}", mem::size_of_val(&obj.foo));
println!("obj.bar:  {}", mem::size_of_val(&obj.bar));
Run Code Online (Sandbox Code Playgroud)

该程序打印:

MyStruct: 8
obj:      8
obj.foo:  1
obj.bar:  4
Run Code Online (Sandbox Code Playgroud)

因此结构的大小大于其字段大小的总和(这将是5).这是为什么?

struct memory-alignment memory-layout rust

3
推荐指数
1
解决办法
249
查看次数

了解循环中的不可变借位

我不太明白为什么会这样编译:

fn main() {
    let mut v = vec![1,2,3];

    for i in 1..v.len() {
            v[i] = 20;
    }
}
Run Code Online (Sandbox Code Playgroud)

...而这不是:

fn main() {
    let mut v = vec![1,2,3];

    for (i,_) in v.iter().enumerate() {
            v[i] = 20;
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

fn main() {
    let mut v = vec![1,2,3];

    for i in 1..v.len() {
            v[i] = 20;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我们都是不可变的借用(一个在调用时len(),另一个在调用时iter())。

因此,我的期望是不应该编译第一个代码段-当存在不可变的借位时,我们在进行赋值时会进行可变的借位。

我有什么误会?

rust borrow-checker

3
推荐指数
1
解决办法
103
查看次数