I'm a big fan of quantum leaps (www.state-machine.com) for c++ embedded. I am not affiliated with them in any way, just had a great experience with it.
I have not used their libraries or tools, but Miro Samek's book is great. There's a C implementation covered in it also. It's a bit of a master class in embedded C programming with careful use of structs and function pointers for "object orientation".
I’m always under the impression that C++ has some issues when it comes to embedded and that only a subset can be used, that the stdlib and stl cannot be used. I still don’t really understand how c++ behaves with exception handling thrown in the mix, where all sort of weird gotchas seemingly come into play.
I get templates, classes, and constexpr might be incredibly valuable though. If used within reason to avoid code size issues.
Has anyone spent serious time writing large firmwares in c++ with teams? What’s debugging like? How do people agree on what subset of the language and it’s plethora of features to use?
it really depends on which embedded you are talking about - 8-bit micros with 128 bytes of RAM and 250mhz 32-bit behemoths are fundamentally not programmed in the same way, and let's not talk about some ARMv8 linux-based embedded which is likely more powerful than the computer you used to play Quake III Arena on.
I'm having some fun with RP2040s and ESP32s these days and I can just use standard C++20 as understood by GCC 12 without specific restrictions except exceptions (and I'm having a lot of fun with it) - hell, there's even some boost:: usage in there.
Pretty much everyone agrees exceptions aren't worth it, but there are plenty of opinions about what the best alternative is (returning bools, error codes, aborting the program, etc.)
Classes are unambiguously good, but polymorphism (specifically vtables) are controversial. Templating is great, but folk love to complain about code size in abstract to sound smart.
Dynamic memory allocations in general are forbidden, but in practice it's occasionally easier to just support it in some very limited way, and then lock the API down very tightly.
> I still don’t really understand how c++ behaves with exception handling thrown in the mix
In my experience you normally disable exceptions when working on embedded code. No RTTI either.
> What’s debugging like?
What's with debugging? Not different to C at all.
> How do people agree on what subset of the language and it’s plethora of features to use?
You agree on the language standard to use, you don't pull dependencies arbitrarily and you keep an eye on the code size and memory usage. Some things might go into project style guide which is a nice thing to have anyway.
Seeing c, seeing the assembly and memory layout, debugging is pretty easy. More than once I’ve ran into C compiler bugs. I can imagine running into the same issue with C++ being pretty troublesome?
Oh. Frankly I've probably never seen a compiler bug in my life. I have to look at the assembly sometimes though when debugging faults of various kinds, and I don't find matching C++ to assembly significantly more complicated than C. There is just a bit of additional knowledge maybe on how vtables work and that's it. Exceptions are probably a pain too, but embedded code doesn't allow them as a rule.
Rust on embedded seems a hell of a lot more viable for large, complicated projects. You can basically use the entire standard library (sans io and alloc, obviously).
Embedded is very conservative. While Rust is looking promising, it will be a while before it is trusted like the embedded subset of C++ is (that is no exceptions and other parts that embedded often turns off). That time may or not find faults with Rust (including some faults that are today considered a good thing).
The movers and shakers in the embedded C++ world are looking at Rust though.
It has got enough attention that SG14 (the C++ embedded working group) is asking questions and trying to figure out what to do about it. Most of the committee seems aware of it, some have looked into it more than others.
That doesn't mean everyone is looking at it. Like I said, embedded is conservative, so it will be a while before everyone looks.
autmotive (plastered with 1bn+$ companies) is actively exploring rust for functional safety, via AUTOSAR, and adacore and ferrous systems partner up for rust in ada-affine industries.
rust has this lovely habit of validating their compiler updates with their full collection of libraries, that's one step ahead of the validation contribution of SUSE, redhat, debian, canonical for common, linux packaged C/C++ libraries, because it happens on multiple OSs.
https://www.etlcpp.com/