4 ms·
Actually, it would. This issue is rather straightforward, caused by not initializing memory. Rust forbids that, consider a following Rust code. struct Exam
by GlitchMr 9y ago
Actually, it would. This issue is rather straightforward, caused by not initializing memory. Rust forbids that, consider a following Rust code.
struct Example {
x: i32,
y: i32,
}
fn example_clone(input: &Example) -> Example {
Example {
x: input.x,
// Oops, forgot y
}
}
This fails with a following error:
error[E0063]: missing field `y` in initializer of `Example`
--> src/main.rs:7:5
|
7 | Example {
| ^^^^^^^ missing `y`
- deleted 9y ago[deleted]
- benmmurphy 9y agoin this kernel's case the caller passed in the output so the bug would not be caught in rust if the same pattern was used. though, possibly this pattern would not be used in a rust kernel.
- GlitchMr 9y agoThe pointer return pattern is mostly due to C limitations. Rust is smart enough to automatically output into a pointer when a structure is big enough (this is invisible in source code, this should be rather optimizer's decision really whether to do it) and supports multiple return arguments by use of tuples. Also, even if somebody did insist on explicit mut-output pattern in Rust anyway, they would quickly realize that they need to initialize the value before getting a mutable reference to it - Rust NEVER allows access to uninitialized memory (other than unsafe blocks where you can trick Rust into accesing uninitialized memory and cause undefined behavior by using `std::mem::uninitialized`). The noise related to it should hint that this is not the intended way to do it. Here is a code example to clarify what I mean. fn write2(out: &mut i32) { *out = 2; } fn main() { let mut two; write2(&mut two); } And error message: error[E0381]: use of possibly uninitialized variable: `two` --> src/main.rs:7:17 | 7 | write2(&mut two); | ^^^ use of possibly uninitialized `two` Fixing that requires explicitly writing a value into `two`, for instance with `let mut two = 0`, which for complex structs... yeah, you may as well return a struct directly instead of bothering with pointer output. [std::mem::uninitialized]: https://doc.rust-lang.org/std/mem/fn.uninitialized.html https://doc.rust-lang.org/std/mem/fn.uninitialized.html
- caf 9y agoIn this case the memory isn't uninitialised - it's been initialised by bio_init(), which sets bi_partno to 0.
- masklinn 9y ago> it's been initialised by bio_init(), which sets bi_partno to 0. It just memsets the entire thing to 0, which in Rust would 1. require unsafe{} 2. most likely be UB as the struct looks like it has a bunch of pointers which would not be nullable (e.g. arrays) And therefore not be done at all, or rejected by reviewers if attempted.
- koverstreet 9y agoYou can return structs just fine in C. The reason it's not generally done in practice is because C lacks return value optimization - the compiler (almost?) always has to do a hidden memcpy() at the end of your function due to pointer aliasing.
- deleted 9y ago[deleted]
- Rusky 9y agoA Rust kernel would likely make this function part of an implementation of the Clone trait, which would lead it to getting the error described above.