Misra C++:2023
forum.misra.org.uk
forum.misra.org.uk
Disclaimer: I'm the founder.
It has been battle tested with real customers in automotive, medical devices, and semiconductors. AFAIK this is the first FOSS tool that achieves commercial use standards (extensive ruleset coverage, low false positives based symbolic execution (which Coverity relies heavily on) and SMT solver, ...)
For enterprise edition simply email to hello[AT]naivesystems.com as noted in the README on GitHub
[1] https://www.ipa.go.jp/publish/qv6pgp00000011mh-att/000065271...
Note the previous MISRA std. predates “modern” c++, as do some others.
Lots of toolchains are pretty conservative also, 2017 is pretty new there. And much like the ISO standard, updates should be a lot easier now.
Currently all C++ implementations are lagging behind ISO, as all major commercial contributors focus in other stacks, and take C++14 / C++17 as good enough for their in-house use of C++.
The bigger three have lost steam, while everyone else is even further behind .
[0] https://en.cppreference.com/w/cpp/compiler_support/17 [0] https://en.cppreference.com/w/cpp/compiler_support/20
Then there is the whole issue that many libraries authors cannot set in stone just one compiler / OS.
Safety-critical automotive software development depends on tool qualification, which is often a lot of tedious work. There must be a spec, there must be tests, there must be proof that the tests cover the full spec, you must have a process to inform users about bugs. There is no free compiler which provides this.
So far our safety guys haven't seen any issues with tool qualification besides requiring everything to be documented and the whole system to be re-tested in case of any tool changes.
The big 3 already support features from C++23 worth learning about https://en.cppreference.com/w/cpp/compiler_support Obviously you can't always use that, but most places with a C++ compiler today support at least some useful features past C++17.
Is it impossible to write a web page that works across browsers? Obviously not. You just need to check caniuse.com.
This kind of landmines is what keeps many code bases still using C++11 and C89.
I agree it is annoying when compilers don't support the same features but my point is the question isn't whether there is an unimplemented feature from that revision in many compilers it's whether the feature you want to use is commonly supported. As an example, if you want widely implemented features like <=> from C++20 then it doesn't really matter most compiler stdlibs don't support riemann_zeta from C++17. Waiting for them to do so only sets you behind years or decades because you're looking for arbitrary features you'll likely never use to be universally supported too.
Rust SAST and DAST tools would be great for all, too.
From https://news.ycombinator.com/item?id=35565960 :
> Additional lists of static analysis, dynamic analysis, SAST, DAST, and other source code analysis tools: https://news.ycombinator.com/item?id=24511280 https://analysis-tools.dev/tools?languages=cpp
Since these are "guidelines for the use of C++17 in critical systems", I would have expected it to prohibit exceptions due to their non-determinstic nature. On a side note, dynamic memory is prohibited (rule 21.6.1).
I haven't read the earlier MISRA C++ guidelines so I don't know if this have changed.
Given that constraint, they conclude that the overhead of maintaining exception unwinding and the non-local control flow aren't worth it.
(To my memory though, Google didn't throw away the benefits of RAII without allowing exceptions... They discouraged complicated behavior in constructors and so the only thing a constructor could fail on was OME, which was supposed to crash anyway).
Almost all systems to which MISRA apply have watchdogs, and crashing to let the watchdog restart the program is a common pattern.
Just crash the system and reboot the MCU can make sense depending on the application. And where it can't, you need to take the same kind of care for handling every single problem at the call site, or correctly propagating it to a layer that can handle it.
Exceptions aren't special here, they are simply a way to do error handling and recovery.
It's the kind of rule that doesn't make sense for applications, but when you've got tightly constrained memory limits, it makes sense.
Your compiler vendor has to pick a (reasonable) behaviour though and apply it consistently, and while they are not required to document it (IIRC - I think that's just for implementation-defined?) you can probably get them to tell you if you have a good support relationship with them. Or you can just figure out what the compiler does, and hope they don't change the behaviour too much with the next release :-)
I suspect you do not want your car's brake controller to do this.
These are just some obvious cases. Not to mention that any use of operator new is UB if memory allocation fails and the system can't throw exceptions.
That's probably not great and might leave data in a bad shape, but it seems better than "undefined behavior" aka no guarantees whatsoever, no?
What compiler does it? At least g++ does not. It is not what specification dictates either.
I can't see how it is a superset either. If the library returns an Option, the calling code can process it as it please, including throwing an exception. On the other hand, if the library only indicates error by throwing an exception, it cannot work with the caller that is built with exceptions disabled.
Otherwise, I should point out I explicitly said "at() with exception support enabled". It's also important the ability to disable exceptions is not a feature of C++, the C++ specs assume exceptions work (just like the Java or C# or Go specs). It is a feature of certain C++ implementations that they suport this mode, just like they support other non-standard features (compiler intrinsics, various #pragmas, etc).
Disabling exceptions is indeed not in the standard, probably because of Stroustrup's position (I respect many of his opinions, but cannot agree with this one) - but it's what every sane compiler, especially a one targeted at embedded systems, will support. Exceptions are designed for a controlled environment where a program terminating will return to somewhere that will maybe add a line to a logging system and restart it automatically. It only complicates things when terminating is an unacceptable scenario.
Regarding exceptions being more code, I very much don't agree. Even for embedded apps, the pattern of "if this fails, wind back up to some top level event loop" is quite common, and exceptions give it to you for free if you're also using RAII. In contrast, with Result<T, E> you have to write code at every level of the stack to handle it. Code which gets particularly ugly when you combine it with things like map() or filter().
The main reason people use C++ over safer languages like Java is performance (memory, CPU speed, real-time constarints etc). And C++ the language is designed for performance, but only with an expectation of a very powerful optimizing compiler. Most C++ std classes are extraordinarily slow and inefficient if compiled without optimizations - certainly much slower than Java for example.
So, C++ is not really C++ without aggressive optimizing compilers. And one of the biggest tools that compiler writers have found to squeeze performance out of C++ code is relying on UB not to happen. That essentially gives the optimizer some ability to reason locally about global behavior: "if that value were nullptr, this would be UB, so that value can't be nullptr so this check is not necessary". And this often extends to the well defined semantics of standard library classes outside their actual implementation - which rely on exceptions.
So, to get defined behavior out of the std classes in the absence of exceptions, either you disable many optimizations entirely, or you carefully write the optimizer to have different logic based on the no-exceptions flag. But, all C++ comittee members and C++ compiler writers believe exceptions are The Right Way, for every situation. So getting them to do quite a lot of work to support someone doing the wrong thing would be very hard.
I think if you disallow exceptions you run into other problems. How can a constructor fail now? You need to have some kind of flag showing if an object is fully constructed. But then that goes against the idea to "make illegal states unrepresentable".
I do wish C++ had more tools to reign in exceptions. Maybe an "onlythrows X" annotation that says only these very specific exceptions may escape from a block, and the checker will complain if it cannot prove that only X can be thrown. The opposite of checked exceptions basically.
Simply passing by value can result in a constructor that fails, while still bypassing any of the factory functions.
If the copy constructor can fail and you don't want that, then delete it?
You're trivialising just how deeply embedded exceptions are into the design of the language.
I gave just one example and it was not meant to be exhaustive, just one 'gotcha' that you won't find out till runtime and your program starts (worst case) giving you slightly incorrect results without you knowing about it...
So, yeah, if you want to do without exceptions (without having your program execute random code) you need to know in advance what special cases to handle, like unintended copy construction, or failures in overloaded operators, or which std libs can be used and which cannot, or which C++ libraries can be linked, and which cannot.
All of which is perfectly possible, but taken together is hardly "easy". It's tedious, error-prone, bloated ... but hardly what someone would call "easy".
I don't understand why jupp0r is getting downvoted?
Most big public c++ projects turn off exceptions, so it seems to be the norm more than anything.
And since both microsoft and meta are adopting rust in their services it seems to me that they are looking for another language than C++. (why else adopt a new language?)
Following seems not to use exceptions(?)
LLVM: https://llvm.org/docs/CodingStandards.html#do-not-use-rtti-o...
AWS: (seems to be using Google's guidelines to be fair)
Webkit: https://gist.github.com/derofim/df604f2bf65a506223464e3ffd96...
Qt: https://doc.qt.io/qt-6/exceptionsafety.html
gcc: https://gcc.gnu.org/codingconventions.html#Exceptions
Unreal: (not totally sure, but I think it uses error codes internally)
Most of the embedded world. + any console game you ever played or heard of.
WebKit, another Apple child.
Qt, it has to support environments where exceptions are not allowed, otherwise they would be losing customers, specially since Qt is older than C++98.
gcc, was initially written in C, and for quite long time had a mixed code base with minimal C++.
The companies adopting Rust aren't doing so because of lack of exceptions, they would still adopt Rust if the language had exceptions support (which panic and std::ops::Try kind of are), rather due to the type safety that C and C++ aren't able to provide.
You would be surprised how many games actually do support exceptions.
Resource exhaustion or hardware failures are the more straightforward use cases for exceptions, but doing anything clever in those cases requires writing similar handling code as you would without exceptions.
I don't see how that relates to the thread, other than to say exceptions in constructors are quite fundamental.
Each object construction is a list of N + 1 construction stages -- constructing the N subobjects (implicitly or as per the initializer list), followed by the constructor body.
The destructor has N + 1 stages too, those match exactly the constructor's stages. If there is an exception happening in any stage of the constructor, say stage E, naturally only stages 0 to E-1 get un-done (in reverse), but not E nor any later stage.
So what you have to do is imagine that all sub-objects are already constructed, and imagine there is a function that runs the constructor body and destructor body in a sequence. The constructor part could throw an exception, causing the destructor part to never run. Like any other function, it should be possible to run it without leaking anything if an exception happens. Make it "exception safe" using RAII or by being extra careful.
If you've written constructor and destructor such that they match in this way (which is, again, like you would write any other function), then will work correctly in all cases. This is a powerful concept and pretty much fool-proof. I say that as someone who has lots of concerns about the language's complexity -- including exceptions.
MISRA C++:2023 Guidelines for the use C++:17 in critical systemsThe good news is that it's very unlikely to happen for any future document version.
(They're comparing with the C version, not the C++ version...)
If Cert has something about an API, then it will have an example of misuse of it and then an example showing its correct use.
MISRA might either prohibit it's use completely (if there's a safe alternative), or with require some boilerplate step be taken every time the API is used.
But as it happens, MISRA C++:2023 doesn't have this guideline.
Can someone give the gist of it?
[0] https://www.brighttalk.com/webcast/18694/602198
[1] bhttps://www.parasoft.com/white-paper/buyers-guide-static-cod...
MISRA C++ 2023 is a massive improvement over the previous (2008) version.
I would imagine all languages will have at least some guidelines relating to how they're used.
Thanks, but no, thanks. I'd rather you completely stop developing software and just let me plug in my phone. The less software my car runs, the safer I feel, and I need nothing more but navigation and music, which my phone handles just fine.
It's used in safety critical systems, like the car computer, which manages the monitoring and adjustment of fuel to oxygen mixture in the engine.
In general, systems that are safety critical or adjacent to such systems should use formal methods. On many newer vehicles, like the Tesla Cybertruck, the infotainment system also doubles as the instrument display, which makes it safety adjacent. As such, it should also use formal methods. Model checking, based on satisfiability, is a relatively low bar to achieve.
MISRA is a decent idiomatic framework that brings one closer to safe coding practices. However, it's not foolproof. Formal methods in theory _is_, but in practice it is not. Defense in depth is useful for designing and writing software. A good idiomatic style, unit testing, and formal methods each provide complementary checks.
So, my recommendation would be to choose a good idiomatic style -- and despite its relative complexity, MISRA is a good idiomatic style from a safety perspective. Then, build a good automated testing culture. Incorporate model checking, especially through any execution path that is safety critical. Finally, architect the system so that failures in things that don't matter (video, audio, "games", or navigation) don't impact things that do matter (instrument display or communication with critical systems).
I think infotainment actually does sit within the safe software process. Likely the lowest. I think static analysis recommendations could be relaxed for ASIL-A... I believe strongly recommended otherwise, which basically means, "you most certainly must do".
Worth pointing out that MISRA is NOT required, even for higher levels; compliance to a standard is. I'm just guessing though chance of C code not so small, if so likely claiming some amount of MISRAness. Though you don't have to do MISRA it's the de facto choice.
They might say we're ASIL-A it doesn't matter. Actually, I think development under those frameworks has ASPICE implications, and many of the same considerations.
A few issues…
- Most people have no idea how many modules there are in their vehicles. It’s a LOT more code than you realize.
- Companies like ERAS, Vector, Kvaser, Mentor, Bosch, and others have a great lock on software for systems they steer via SAE and ISO.
- AutoSar and other shitty systems. It doesn’t matter how good your programmers are if they are kneecapped out the gate.
- Same as any programming lately at big companies… it’s 10 managers to every actual programmer.
- Outsourced. When I was at a Chrysler, code was worked on, released, and tested locally for some modules. Now… often times no one at Chrysler may even be allowed to see code. A LOT of work is done in India.
MISRA isn’t even close to a problem in automotive. And I disagree it’s a wage problem. You could pay the engineers in India more, and it still wouldn’t give them any idea how the consumer will use the end product. It doesn’t help them understand repair/replace diagnostics. No one is monitoring the ever increasing complexity of the systems as a whole.
Overall, cars do work well. But damn if they aren’t trying to ruin that.
Companies like Bosh have a strange dev process where they don't want to change code but instead make almost everything tunable by parameters so that you essentially can program via config, to get around some internal process.
Their code is a nightmare to interface with.
AutoSar is a joke. I would rather each device have their own API then dealing with that dynamic complex mess.
Somewhat related to the proliferation of AutoSAR, but AutoSAR is just the solution, whether you like it or not. It could be replaced with some hypothetical "PerfectSAR", and this remains true.
None of this is exactly brand new. That said, the extent of the situation is worrying. Combine with this that we're trying to deliver so much more on tighter schedules... seems like a recipe for disaster.
Programming simple ECUs without bloat for a car is done quickly. Except the engine and ABS system. You got sensitive control loops in those. Those two systems is probably almost all programming work.
Most of the components are designed by suppliers they partner with. I don't know that you're going to find a good hyperlink for this stuff.