-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Book section: Tips for embedded C / C++ developers #126
Comments
I wrote an article some time ago, about some Rust patterns that replaces C pointers. Might be helpful in this context too? |
One thing that is quite popular now is to use In C++ there is a continuous move towards If we can answer these a bit I believe it would be good for convincing the embedded C++ (library) developer. |
@korken89 No idea where you got that from. It's pretty much exactly the other way around: In Rust variables are const by default and everything is fully propagated through the compilation passes meaning that most functions will just turn into hot air leaving only few instructions behind. All automatically and per default without fiddling with functions trying to convince the compiler to that something is const. It's truly zero cost abstractions something that C++ never really achieved. Mind you, the incredibly optimised binaries is something you will only get with release builds; debug builds are a bloat nightmare. The problems are more on the opposite side of the spectrum: The safety guarantees of Rust make it rather cumbersome to share data, work with self-referential data structures or (especially in embedded areas) work with dynamic amounts of data. |
I got it from a lot of embedded development (libraries, OSes, and firmwares) in C++ together with participation in the embedded and metaprogramming C++ communities, and now rewriting my C++ libraries into Rust.
I am aware of what you speak, but it is up to the user to make sure that a function will be evaluated at compile time. The simple example, is to give inputs that are runtime dependent, without realizing it, and the compiler will gladly generate runtime code for it rather than to generate a compile time error. Moreover, the LLVM backend is not omnipotent, and assuming that the compiler will optimize everything away does not always happen (unless there is something new I have missed that guarantees this), there are some really good talks on YouTube by Chandler Carruth on the optimization LLVM does, which gives a good view into how well it will optimize and what the limits are.
Here you are misinformed, But indeed, there are some parts of C++ which truly are not zero cost.
Indeed, and this is a significant issue. One way to solve it in C++ is to use value based metaprogramming and a
I am talking about compile time data structures in this case (stored in flash or used to initialize a run-time data structure), run-time data follows the normal Rust way and it is assumed that the readers have read the Rust book before coming here. Please see the Back to the question at hand now, as coming from a C++ perspective these questions are still active and I still believe that it should be covered to some extent. |
In Rust? No. It's not even possible to ensure that. (Well, with the exception of const functions but they're only usable for initialisation of static data and often not even that).
No, not quite. I'm fully aware that this is a goal of C++ and can be achieved by expert programmers but is except for a few exceptions not done due to being extremely time consuming. Also with C++ that works only inside a single compilation unit or when excessively using code in header files (which a lot of other people, me included, frown upon), which is neither possible in Rust nor necessary.
I also have some C++ background (and consider myself an expert C programmer) and have experienced the exact opposite of what you're trying to say needs fixing/documentation. Proper zero cost abstractions in C++ require a tremendous amount of effort to implement and ecosystem support (which often simply does not exist) and just happen to work out of the box in Rust, which is one of the main reasons why I completely gave up on embedded C/C++ development. I'd really like to learn more about the problems you're facing because I have a strong suspicion there's an easy fix to your problem and yes, that's something that should go in the book, too. |
The last few comments sound extremely confused to me, probably in part because In both C++ and Rust, it is trivial to force the compiler to evaluate something at compile-time or error if it cannot; you simply declare a variable to be For actual template metaprogramming that @korken89 Does that answer your questions? |
Indeed, and I have been creating these kind of abstrations through header-only libraries as you said.
@Ixrec really hit it on the nail here, thanks for the clarifications! The building block that I use in libraries for embedded system is I was not aware about |
@korken89 You might want to have a look at macros, too, to generate tables and/or runtime expressions at compile time. |
@therealprof Thanks, I'm already there :) Trying to learn procedural macros now. |
IMO, how to use the build system for cross-compiling to embedded systems is the most important thing to put in this section, if it's not already somewhere else. At least that's what I had most issues with when switching to Rust for embedded development :) I guess that's going to be better with upstreaming of xargo into cargo, though. |
This issue was moved to rust-embedded/book#9 |
We agreed on having a section containing tips for embedded developers that have a C / C++ background. For example, they may be used to using for loop + indexing on arrays but it's more efficient to use iterators in Rust so they should use that instead.
Anything else that should be covered? cc @thejpster
The text was updated successfully, but these errors were encountered: