Earlier quoted context omitted.
I've seen this error a lot when working with two different versions of the same library. Specifically, you can directly include version A, but a different library depends on a version B, with some of that exposed in the public API.
I think the compiler will now give you a hint that they may be from different versions. If not, next time you see it you should open up a bug in rustc. To anyone who gets a cryptic error message - that's a bug, report it.
Uninitialized memory: Unsafe Rust is too hard
101–110 of 127 posts
Re: Uninitialized memory: Unsafe Rust is too hard
#102Earlier quoted context omitted.
I suspect you might start to receive a bunch of replies from people with the opposite experience (replies from people who find the syntax easy to read, and the compiler errors clear and understandable). I would like to attempt to preempt that by noting that it's totally reasonable for two people to feel drastically different things about a programming language. Neither view is more correct than the other. That said,…
> That said, I am curious why different people have these different feelings. One aspect is likely rooted in the fact all of our brains are different. But I also wonder if first impressions play a big role here. Path dependency has big impact on what seems natural, intuitive, etc. Part of that is what you've done before, and part is first impressions, and part of it is your approach to learning (or the approach takin…
Re: Uninitialized memory: Unsafe Rust is too hard
#103Earlier quoted context omitted.
Is it actually achieving that goal though if the advice is "use C if you have to do `unsafe` stuff"? That's really my point. IMO the language was always intended to be able to be used in any situation C is used (with maybe a few exceptions), which includes situations where `unsafe` is necessary.
For starters, the example I gave (Actix framework) had no such situations where unsafe code was imperative to having it function. That's where the drama originated from there. Secondly, I don't think the goal of Rust is to rewrite the entire kernel (or replace C/C++ for that matter). Rust is optimized around writing ergonomic, safe code. It's compiler is designed to produce high-performance binaries with minimal UB.…
> Rust has remained true to its goal of providing the safety and convenience of modern programming languages, while still offering the efficiency and low-level control that C and C++ offer.
> When used in its own most minimal configuration, it is even possible to write an operating systems kernel in Rust.
> The resulting design is not only simpler to learn, but it is also much "closer to the metal" than we ever thought possible before. All Rust language constructs have a very direct mapping to machine operations, and Rust has no required runtime or external dependencies.
They do actually have a group working on making `unsafe` better, so they do somewhat recognize the problem (I'm not sure about the results, but the last time I looked at it was probably over a year ago): https://github.com/rust-lang/unsafe-code-guidelines
Perhaps another catch is that, at least in my experience, the most common situation where `unsafe` can into play is interop with other languages/libraries/etc.. Some of it is avoidable, but a certain amount of it is necessary just be able to interface with existing non-Rust code, so it's not really optional in those situations.
Also, just to be clear, I do actually like Rust, and I've written a few different things in it. I just think the state of `unsafe` is poor to the point that it's very hard to determine if you're doing something correctly, which in my opinion makes unsafe unusable for its purpose.
[0]: https://blog.rust-lang.org/2014/09/15/Rust-1.0.html
Edit: To be clear, I'm not attempting to defend Actix, that was silly. I'm just talking about situations where unsafe is unavoidable, which really covers a lot of potential usages of Rust.
Re: Uninitialized memory: Unsafe Rust is too hard
#104Earlier quoted context omitted.
Aren't all the `(*role)` in their code "mutable references" too? (*role).name = "basic";
No, this is specifically not creating a mutable reference. So it's fine except for the fact that writing via assignment like this calls the destructor/drop for the old value, if the type has a Drop implementation. That's why &str is fine but String is not, since it will call Drop on a zeroed String (Which is not guaranteed to work) or on an uninitialized String. Using ptr::write instead explicitly does not Drop the o…
You mention ptr::write() but it is not used here, and I don't see how you could use it to write to a field?
Re: Uninitialized memory: Unsafe Rust is too hard
#105Earlier quoted context omitted.
In the spirit of being charitable, I would say that the article is highlighting a place where the guarantees are incompletely documented. And not having a solid specification and clear documentation is absolutely one of the things that makes unsafe Rust hard. I'd actually like to qualify that a bit. Doing unsafe is not especially hard, just use pointers everywhere instead of references. That's exactly like C (which d…
> In the spirit of being charitable You are being nice, but even if there is a documentation error, we can prove that if safe rust isn't completely broken, and `& x.field` is allowed in safe Rust, then fields must be aligned. It is just preposterous Rust would be more broken than C in this regard. > but the syntax is clunkier, you have to use function calls instead of concise operators like * and ->. Yes I agree, the…
Re: Uninitialized memory: Unsafe Rust is too hard
#106Earlier quoted context omitted.
Another good example is Win32, in many cases only the length is initialized and the API does the rest, this allows them to change the ABI across versions without impacting the caller.
That should work perfectly with multiple structs. Define #[repr("C")] struct MyThing { length: usize, data: MaybeUninit } Then initialize with sizeof(data) and MaybeUninit::uninitialized(). When the call is complete, assume_init() and access the fields of the result struct as normal.
Re: Uninitialized memory: Unsafe Rust is too hard
#107Earlier quoted context omitted.
I don't buy into editions, for me I hardly see them any different from language version switches available across programming languages. Mainly, because: 1 - They require the whole code, including all third party dependencies to be available to the compiler; 2 - There is the issue about possible inconsistencies across Rust compilers, when they start to be more widespread; 3 - They are relatively constrained the scope…
(All responding to 1) A. Binary dependencies were a mistake. B. No, editions absolutely do not require all dependencies to be fully available in source. Editions are purely a front end thing and as long as you have enough info for the api/abi, you're fine. C. Headers are still source code. You cannot use any dependency without partial source, meaning we'd be stuck with that anyway.
If Rust doesn't want the enterprise and game development markets it is ok, there is enough space for all.
Re: Uninitialized memory: Unsafe Rust is too hard
#108Earlier quoted context omitted.
There may of course be rare cases where having it uninitialized helps, but I would wager that even than the compiler could optimize it more often than not.
It's not that simple. Like the unused bu allocated space in a Vec is basically a `[MaybeUninit ]`. Or in async runtimes you often have an unsized type with an future trait object inlined (through unsized types anyway need a bit more love ;=) ). Or some C FFI patterns. But yes I would say in pure rust the use cases for `MaybeUninit` are rare, and the cases where you need pointers to fields even rarer. Though while rar…
Re: Uninitialized memory: Unsafe Rust is too hard
#109Without any unsafe code this is simply: let role = Role { name: "basic", flag: 1, disabled: false, }; The language tries to prevent you from interacting with a `Role` object that's not fully initialized. `mem::zero()` could work, but then you'll have to turn the `&'static str` into an `Option ` or a raw pointer, to indicate that it might be null. You could also add `#[derive(Default)]` to the struct, to automatically…
I remember that after reading the Rust book, one of the first things I tried to do was to load a struct from a file. Like pseudocode:
struct MY_STRUCT my_struct;
read(file, &my_struct, sizeof(my_struct));
2 lines of code.... It should be simple, right? RiGhT?! Well, the first stackoverflow answer involved unsafe and a bunch of other stuff I didn't understand. And also I thought that as a beginner I shouldn't start fiddling with unsafe right away (otherwise, what's the point? I'm trying to move away from C). Then I learned that structs are not laid out as declared (OMG!), etc.So, thinking this went beyond my skills I left it aside and tried to make a nice console logging library for my projects. It should be simple! I tried to create a variadic function and you can guess how it went.
I am out of luck with Rust.
Re: Uninitialized memory: Unsafe Rust is too hard
#110Earlier quoted context omitted.
If I understand correctly, reading [0], in C99 (or later) you can do that with struct MyStruct foo = {}; This has the effect of initializing all members to zero (or, more precisely, the value which is the same as for objects that have static storage duration [0]). [0] https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html See also Stop Memsetting Structures : https://news.ycombinator.com/item?id=19766930
You need to put something in those braces. An empty initializer list is not allowed by C99 or C11. That being said, you only need to put ONE thing in there, the rest will then be initialized as you described.
That's what I get for using GCC as an approximation of the C standard. (By default, GCC permits empty initializer lists.)