As someone who works on the innards of a cooperative multitasking embedded OS for a living, I am sick and tired of C and C++.<p>Closures is a huge one. Everything is async in HW land, an interrupt fires and calls you when data is ready, so doing a read looks like<p><pre><code> MyOpInitialFunction()
{
// Business Logic
AsyncReadFromFlash(sDataBuffer, sizeOfBuff, sizeToRead MyOpFirstCallback, contextVar);
}
MyOpFirstCallback(byte* dataBuf, size_t sizeRead, void* context)
{
//Business logic, use data read in some how
AsyncReadFromFlash(sDataBuffer, sizeOfBuff, sizeToRead MyOpSecondCallback, contextVar);
}
MyOpSecondCallback(byte* dataBuf, size_t sizeRead, void* context)
// and so on and so forth
</code></pre>
It gets boring really fast. The system has a nice DMA controller that we use a lot, so a similar pattern exists for copying large chunks of data around.<p>You can actually implement a variant of closures in C using Macros, and right now the entire team wishes we had done that! (It isn't hard, in embedded land you have complete memory control, you can just memcopy the entire stack down to a given known location and memcopy it back to resume!)<p>Rust has a lot of features that are really useful for embedded, the problem is that it is going to be a long time, if ever, that the embedded world switches over.<p>Embedded systems tend to have very little code space, so efficiency of generated code is a must. LLVM and even GCC aren't as efficient as ARM's (horribly overpriced, feature lacking) compilers. The one thing ARM's compilers do though is minimize code space, and they do a very good job at it.<p>The other issue is that any sort of language run time is questionable. Even the C Run Time is typically not included in embedded (teams opt out of using it), if you want printf you typically write whatever subset of printf functionality you want!<p>Oddly enough memory safety is not a real issue, though slightly better buffer overrun protection than what we get from static analysis would be nice!<p>Consumers hand over a destination buffer to Producers, who return it in a callback. Because of the above async pattern, the consumer isn't even running until the data is ready.<p>That's solved 99% of our issues. :) (If you want someone else's data, you ask for it and get it passed in a buffer you provide!)