Earlier quoted context omitted.
Rust is promoted all the time as the sensible choice for embedded work instead of C or C++.
The thing is “embedded” is an extremely broad space. There’s a bunch of Rust stuff going on in some corners, and absolutely none in others.
Debunking that C++ is faster and safer than Rust
61–70 of 84 posts
Re: Debunking that C++ is faster and safer than Rust
#62Just looking from afar, I don't have time to analyze every other claim, but this one: > Both C++ and Rust have generated identical assembly listings; both have added push rbx for the sake of stack alignment. Q.E.D. seems to be completely wrong: a decent compiler is able to align the stack without "touching" it. For the variables inside of the function to be pushed to the aligned stack position, only different offsets…
Re: Debunking that C++ is faster and safer than Rust
#63> As you can see, the documented behavior and the absence of undefined behavior due to signed overflows do make life easier. Not having undefined behavior does make life easier, but having it be defined and then giving the example which benefits from the way that Rust chooses to define it is not really fair. > With less effort, Rust generates less assembly code. And you don't need to give any clues to the compiler by…
> the example which benefits from the way that Rust chooses to define it I'm actually struggling to see what the practical benefit is in having it wrap around. The program is still producing garbage at that point, which you're not handling, so why not let the compiler just forget about that case just like you already did?
Re: Debunking that C++ is faster and safer than Rust
#64Earlier quoted context omitted.
Different type? Sure. Disadvantage is that it’s not pervasive. Compiler flag? Probably, I am not an expert on compiler flags that change language semantics; we don’t do that in Rust, but I know C and C++ compilers do.
> Compiler flag? Probably, I am not an expert on compiler flags that change language semantics; we don’t do that in Rust, but I know C and C++ compilers do. What do you mean? Is Rust's -C overflow-checks just a joke then? https://doc.rust-lang.org/reference/expressions/operator-exp...
* There are two modes for overflow checking: enabled, and default.
* If overflow checking is in "enabled" mode, overflow results in a panic.
* If overflow checking is in "default" mode, the results are two's compliment wrapping.
* Debug builds are "enabled" mode.
(There's a few other details, but this is good enough for our discussion. See https://github.com/rust-lang/rfcs/blob/master/text/0560-inte... )
Rustc implements this as follows:
* When debug_assertions is on, it's in "enabled" mode.
* Otherwise, it’s in “default” mode.
* -C overflow-checks turns on "enabled" mode, regardless of other settings.
This is completely consistent with the rules of the language. If these checks ever get cheap enough, rustc may even start to turn them on by default, which is also acceptable under these rules. We'll see if that ever happens, though.
Re: Debunking that C++ is faster and safer than Rust
#65Earlier quoted context omitted.
You are correct, it has nothing to do with alignment. rbx is a callee-saved register, so the callee saves it.
Do you mean thar rax is caller-saved?
int bar(int a, int b) {
int z = a * b;
foo();
return z;
}
https://godbolt.org/z/a8Y35rWhere to put `z`? It has to be someplace where `foo` won't clobber it, like a callee-saved register - in this case ebx.
But now `bar` is responsible for saving the value of ebx for its caller. That explains the push and pop.
Alignment is unrelated; this is just about calling conventions.
Re: Debunking that C++ is faster and safer than Rust
#66Here's a case I stumble on: Rust seems to generate unnecessary branches. Compare copying an optional range: C++: https://godbolt.org/z/VCf638 Rust: https://rust.godbolt.org/z/jRFiw_ I think the key difference here is that C++ allows specializing optional on trivial types - can anyone shed more light?
Is this a remnant of #[inline] on Option's Clone impl methods?
With "larger" types (e.g. an optional several-GiB array) it seems like this could save some time depending on where things are in memory.
Re: Debunking that C++ is faster and safer than Rust
#67Earlier quoted context omitted.
> Compiler flag? Probably, I am not an expert on compiler flags that change language semantics; we don’t do that in Rust, but I know C and C++ compilers do. What do you mean? Is Rust's -C overflow-checks just a joke then? https://doc.rust-lang.org/reference/expressions/operator-exp...
Okay, so let's review the language's rules here: * There are two modes for overflow checking: enabled, and default. * If overflow checking is in "enabled" mode, overflow results in a panic. * If overflow checking is in "default" mode, the results are two's compliment wrapping. * Debug builds are "enabled" mode. (There's a few other details, but this is good enough for our discussion. See https://github.com/rust-lang/…
Re: Debunking that C++ is faster and safer than Rust
#68Earlier quoted context omitted.
Okay, so let's review the language's rules here: * There are two modes for overflow checking: enabled, and default. * If overflow checking is in "enabled" mode, overflow results in a panic. * If overflow checking is in "default" mode, the results are two's compliment wrapping. * Debug builds are "enabled" mode. (There's a few other details, but this is good enough for our discussion. See https://github.com/rust-lang/…
So let's review where we are right now. C++ left the entire thing undefined , which gave compilers the complete freedom to add flags that define e.g. wrap-around or trapping or other behavior. I suggested you can use such flags if you want. You complained about that and said it's "changing" language semantics... despite the fact that it's 100% consistent with the "rules of the language". You even went on to claim "we…
Re: Debunking that C++ is faster and safer than Rust
#69Earlier quoted context omitted.
So let's review where we are right now. C++ left the entire thing undefined , which gave compilers the complete freedom to add flags that define e.g. wrap-around or trapping or other behavior. I suggested you can use such flags if you want. You complained about that and said it's "changing" language semantics... despite the fact that it's 100% consistent with the "rules of the language". You even went on to claim "we…
Undefined behavior is different from implementation defined behavior. Code that exhibits UB is not a valid program. Flags that take UB and define it are categorically different than flags that tweak various options, because flags that define UB expand the set of valid programs, where flags that tweak options do not.
Undefined behavior is behavior that the language does not define, not behavior that the implementation is prohibited from defining. That's why you can't treat it like (for example) a random-number generator. Implementations are well within their rights (i.e. 100% consistent with the language) to define previously-undefined behavior to be anything. They're also just as welcome to leave them undefined. Both are 100% consistent with the language and neither is "changing" the language semantics. No program that exhibited UB is going to misbehave somehow just because someone decided to define the behavior under UB. The semantics already allowed anything to happen. Whatever they define falls under "anything could happen".
Implementation-behavior is behavior that the the implementation is guaranteed to define. Like with UB, the implementation has freedom to choose a behavior. Unlike with UB, it is not allowed to leave that behavior undefined. So the program can be sure to have a well-defined output.
It is completely wrong to simultaneously say changing "wrap" to "crash" is "not changing semantics" and somehow "consistent" with the language rules, but that changing "undefined" to "wrap" is "changing semantics" and "not consistent" with the language rules. If the language wraps on overflow, then changing that to a panic is actively shrinking the set of valid programs; valid programs that used to behave one way now behave differently. (They crash!) The latter is merely expanding the set of valid programs; programs that had no rights to claim any behavior under UB now actually have a right to claim something under the implementation, but that doesn't change the behavior of previously-valid programs. They're still provided exactly the same guarantees they already were.
(P.S., UB isn't even a property of a program, but of an execution. But I'll leave that out since the simplified version is clearly confusing enough as-is.)
Re: Debunking that C++ is faster and safer than Rust
#70Earlier quoted context omitted.
Undefined behavior is different from implementation defined behavior. Code that exhibits UB is not a valid program. Flags that take UB and define it are categorically different than flags that tweak various options, because flags that define UB expand the set of valid programs, where flags that tweak options do not.
Okay, you're very confused. You're getting it almost backwards. Undefined behavior is behavior that the language does not define , not behavior that the implementation is prohibited from defining. That's why you can't treat it like (for example) a random-number generator. Implementations are well within their rights (i.e. 100% consistent with the language) to define previously-undefined behavior to be anything . They…
(As well as that overflow is UB in one language and not another, of course.)