An opinionated and needlessly specific list. For example, this Use minimally two assertions per function on average should've been Assert your invariants And this Do not use goto statements is a controversial advice at best, because there are several well-established goto-based patterns that produce a much cleaner code.
I would also say perhaps avoid recursion should be revised to avoid non-tail-call recursion Because the justification to avoid recursion is basically avoid running into the limit of stack, and tail-call recursion uses no stack space at all. Of course you still might end up with situations where the function does not terminate, but simple loops can do that too. In relation to Rule No.2, it is also possible to prove an…
Rules for Writing Safety Critical Code (2006)
71–80 of 82 posts
Re: Rules for Writing Safety Critical Code (2006)
#72Earlier quoted context omitted.
Space software? Nice! Going to check out MISRA now. FWIW the initial page just reflects the JPL publication "The Power of Ten – Rules for Developing Safety Critical Code" by Gerard Holzmann [0] [0]: http://spinroot.com/gerard/pdf/P10.pdf
Gerard Holzmann is the main author of the formal software verification tool "spin" as well as the owner of spinroot.com. I took a class on formal verification under him at Caltech.
Re: Rules for Writing Safety Critical Code (2006)
#73Many commercial (and open source) static analyzers will have checks that are hard to codify in rules that are digestible by humans. For example, most analyzers that use sophisticated interprocedural analysis will not be easily described as a guideline for humans, unless those humans are compiler engineers. This is especially true for analyzers that have heuristics built in to minimize false positives, which is most often a real-world requirement.
[1] https://www.securecoding.cert.org/confluence/pages/viewpage....
Re: Rules for Writing Safety Critical Code (2006)
#74Why not just call it "Rules for Writing Code"? Who would ever, for example, consider checking the return value of some function but then think "ah, this isn't safety critical, I'm just skip writing a quick _if_ statement and then leave this as a place that mysterious bugs can arise"? Same thing with assertions.
Have you met programmers? Less snarkily, there are billions of lines of production code that don't check return values for malloc(), printf(), and so on because those failures are extremely rare and difficult to handle sensibly. Banning dynamic allocation would ban large areas of programming language - Lisp, Python, Javascript, and so on.
A system OOM may actually show a soft behavior, whereby the whole system thrashes more and more until it grinds to a halt. Whatever your program does is futile and irrelevant.
To QA the program for how it handles null out of malloc, you need to tweak the setup: disable overcommit and simulate low memory conditions. (Or even just switch to an alternative allocator that simulates failures.)
Checking the result of malloc for null is of course good for maximal portability: your code can be reused where the check actually means something.
Checking for null and not testing that logic is almost no better than not testing at all (in keeping with the general hypothesis that untested code is junk).
Re: Rules for Writing Safety Critical Code (2006)
#75Earlier quoted context omitted.
Because these rules have a cost, and sometimes the cost is not worth it for non-safety critical code. It would be a PITA for general purpose code to avoid all dynamic memory allocation.
With the sole exception of item (3) in that list (pertaining to dynamic allocation), which others carry a cost?
Giving all loops a fixed upper bound comes at a cost to code readability (consider the example of traversing a linked list, as given in the article).
Re: Rules for Writing Safety Critical Code (2006)
#76Rules like avoiding recursion and loop upper bounds are partly justified by helping code analyzers to prove executions are bounded. Does anyone have experience performing formal static analysis on code? And if so, are there any open-source examples of the state-of-the-art tools being used on nontrivial problems? I've been looking at this recently, but I've never seen a proof of reasonably standard function like, say,…
Take a look at dafny [1] and F* [2]. Both are open-source and it appears that both of them are able to prove code to be correct with considerably less proof code than traditional interactive theorem provers (such as Coq or Isabelle), mostly thanks to the use of an SMT solver (Z3, in both cases) to aid in proving. Both languages are being used in Project Everest [3], which is building a formally verified HTTPS stack,…
And you wonder why you're not getting any traction.
Dafny, though, seems to have the right idea.
Re: Rules for Writing Safety Critical Code (2006)
#77Re: Rules for Writing Safety Critical Code (2006)
#78Earlier quoted context omitted.
seL4 is the big one: https://sel4.systems/ Here's a general reference of open source microkernel operating systems: http://www.microkernel.info/ Here's a general reference for open source real time operating systems: http://www.osrtos.com/
seL4 is really sexy, but I don't think it's anywhere near the most-used one?
Re: Rules for Writing Safety Critical Code (2006)
#79I work on software that goes to space. I believe we and NASA use the MISRA coding standard, which is effectively this but taken to extremes. If you actually want to create safety critical code I would recommend that you familiarize yourself with the MISRA ruleset and DO-178B.
EDIT: And to those of you debating whether all of these rules are necessary and good -- they are; however, they are a subset. We use an internal coding standard that resembles MISRA C but does have some modifications. The only rule of his that we don't do nearly the same way is the 60 line limit. We use code complexity metrics rather than a strict line limit, but it's the same idea.
Re: Rules for Writing Safety Critical Code (2006)
#80Earlier quoted context omitted.
Manual conversion to a loop also destroys the same information, so it’s a wash either way on that front.
You can't convert arbitrary tail calls to a loop. You can only convert recursive tail calls to a loop. The information loss associated with non-recursive tail calls is great. It's true that recursive tail calls lose less information, but it is not true that it's equivalent to the information lost in a loop. In a loop you always have access to {head, current, tail} while in a tail call you might (subject to algorithm…
These rules are mostly geared towards C, which doesn't guarantee TCO at all.
[1] Partly as way to learn Lua and TCO, and as a way to manage Cisco router config files in a version control system.