Earlier quoted context omitted.
The problem, as I understand it, is that Rust's ownership semantics don't accommodate for the kinds of programming needed by 0 dynamic allocations. Lots of intrusive nodes pointing freely at one another, is an example. I've heard some Rust libraries approximate intrusive allocations almost perfectly, but not quite perfect.
As long as you're willing to use unsafe, you can write things exactly as you can as in C. That's of course, not as satisfying as not needing to, but by encapsulating that in a library and providing a safe interface, downstream users still get the benefits.
The Problem with Friendly C
161–170 of 174 posts
Re: The Problem with Friendly C
#162Earlier quoted context omitted.
The problem, as I understand it, is that Rust's ownership semantics don't accommodate for the kinds of programming needed by 0 dynamic allocations. Lots of intrusive nodes pointing freely at one another, is an example. I've heard some Rust libraries approximate intrusive allocations almost perfectly, but not quite perfect.
Rust's ownership and borrowing rules are entirely a compile-time thing: they just determine what objects can be safely used, and when. There is absolutely no need to use dynamic allocation to benefit from Rust's ownership and borrowing checks. And none of the other core language facilities (primitive types, unsafe pointers, fixed-size arrays) require dynamic allocation either. What does require dynamic allocation is…
Re: The Problem with Friendly C
#163Earlier quoted context omitted.
It's not really about optimisations, but more about being able to translate directly to fast machine instructions (which may behave differently on different machines). What I'm talking about is not adding checks, but what happens when the compiler knows that something has undefined behavior through e.g. Constant propagation. This happens in the optimizer on IR level. The undefined behaviour is there to make translati…
> What I'm talking about is not adding checks, but what happens when the compiler knows that something has undefined behavior through e.g. Constant propagation. But ... either the compiler can prove at compile time that the program has undefined behaviour, in which case it should simply refuse to compile, or it can not, in which case it has to emit a runtime check to determine when undefined behaviour "is about to ha…
It's more fine-grained: The front end (namely clang in llvm) in easy cases can already see that something is always undefined behaviour and it will omit a warning (for instance through constant propagation). This happens with `i = 32; xThe optimizer then does stuff like inlining function that lets it see even more places where there sure will be undefined behaviour. This is the point I'm talking about. The compiler already knows that it will be undefined behaviour - no checks are needed. Performance is of no concern here, as the program already is in a buggy state and may just quit. This will happen when you have the function call f(32) in one function and in `f` there's a shift `x Where performance matters is the case where the compiler doesn't know the parameter. To be completely safe the compiler would need to check wether the shift amount is over 31 (`if shamt > 31 { exit(0)} else { x >> shamt }`). Here there's also a performance hit in case there is no undefined behaviour occurring.
Re: The Problem with Friendly C
#164Earlier quoted context omitted.
Rust's ownership and borrowing rules are entirely a compile-time thing: they just determine what objects can be safely used, and when. There is absolutely no need to use dynamic allocation to benefit from Rust's ownership and borrowing checks. And none of the other core language facilities (primitive types, unsafe pointers, fixed-size arrays) require dynamic allocation either. What does require dynamic allocation is…
As far as I know, nobody managed to create a comprehensive intrusive data structure library that behaves as optimally as in C, due to the ownership semantic restrictions.
Also, I would contend that, for the vast majority of programs, the benefits of a simple, hierarchical, statically enforceable resource management scheme like RAII outweigh the downsides. Programs that need more sophisticated approaches are a very small minority.
Re: The Problem with Friendly C
#165Earlier quoted context omitted.
> What I'm talking about is not adding checks, but what happens when the compiler knows that something has undefined behavior through e.g. Constant propagation. But ... either the compiler can prove at compile time that the program has undefined behaviour, in which case it should simply refuse to compile, or it can not, in which case it has to emit a runtime check to determine when undefined behaviour "is about to ha…
> But ... either the compiler can prove at compile time that the program has undefined behaviour, in which case it should simply refuse to compile, or it can not, in which case it has to emit a runtime check to determine when undefined behaviour "is about to happen", which is potentially expensive? It's more fine-grained: The front end (namely clang in llvm) in easy cases can already see that something is always unde…
You have it all backwards. If there is some place in the control flow of the program where the compiler can prove that the program is guaranteed to run into undefined behaviour, then it's either because it has proved that the whole program unavoidably runs into undefined behaviour (in which case the compiler should simply refuse to compile), or because there is a branching instruction preceding that part of the code that divides the control flow into the part that the compiler has proved to run into undefined behaviour and the part where the compiler has not proved that, in which case you obviously have a branching instruction (and probably associated condition computations) that has the function of "performing a runtime check" and that introduces an overhead vs. simply dropping that check/branch from the code.
If the program somehow determines at runtime whether it is in a defined or an undefined state, there has to be code to make that determination--code that the optimizer could avoid producing/eliminate as far as language semantics are concerned, as it doesn't have to guarantee any specific behaviour in the undefined case, so simply having the undefined case execute the same code as the defined case, thus avoiding the check to discern the cases, makes the defined case faster.
Re: The Problem with Friendly C
#166Earlier quoted context omitted.
As long as you're willing to use unsafe, you can write things exactly as you can as in C. That's of course, not as satisfying as not needing to, but by encapsulating that in a library and providing a safe interface, downstream users still get the benefits.
Can a safe interface always be provided?
Re: The Problem with Friendly C
#167Earlier quoted context omitted.
That doesn't do IPC though right? When I say IPC, I mean where you have a Rust process and and a C/C++ process running with different privileges. When people say FFI, they mean Rust code and C code running in the same process. I thought Chromium had a library for this (for multiple C++ processes), but I guess it is sort of ad hoc now? https://www.chromium.org/developers/design-documents/inter-p... https://www.chromiu…
https://github.com/pcwalton/gaol
Though it's great to see this, because just rewriting in Rust -- while fantastically expensive -- isn't necessarily enough. You need multiple security measures. The grandparent comment was mistaken about this.
Re: The Problem with Friendly C
#168Earlier quoted context omitted.
> As I see it that's a variant of PADDW, so whatever PADDW does is what matters, and PADDW does twos complement. Nope, PADDW is a variant of PADDSW, so whatever PADDSW does is what matters, and PADDSW does saturating addition. Or in other words: You are defining "normal" to mean "twos-complement with wrap-around" after all, which makes it rather unsurprising that every "normal" instruction according to your definitio…
"ascii adjust after addition" > Nope, PADDW is a variant of PADDSW, so whatever PADDSW does is what matters, and PADDSW does saturating addition. That's like arguing that Red Sports Car is a variant of Red Sports Car with Stripes. The one that adds adjectives is the variant, the one without those adjectives is the base. If PADDW did saturating arithmetic and PADDWW did wrapping, I would agree with you, but that's not…
Re: The Problem with Friendly C
#169Re: The Problem with Friendly C
#170Earlier quoted context omitted.
"ascii adjust after addition" > Nope, PADDW is a variant of PADDSW, so whatever PADDSW does is what matters, and PADDSW does saturating addition. That's like arguing that Red Sports Car is a variant of Red Sports Car with Stripes. The one that adds adjectives is the variant, the one without those adjectives is the base. If PADDW did saturating arithmetic and PADDWW did wrapping, I would agree with you, but that's not…
It is, however, what many DSPs do.