
Comments on the MISRA C coding guidelines (2011) - kick
http://www.knosof.co.uk/misracom.html
======
enriquto
A nice complement (and a generalization) of the MISRA C guidelines are the
NASA/JPL C guidelines [1], which are also a very beautiful read. They can be
succinctly summarized as ten simple rules [2] :

1\. Avoid complex flow constructs, such as goto and recursion.

2\. All loops must have fixed bounds. This prevents runaway code.

3\. Avoid heap memory allocation.

4\. Restrict functions to a single printed page.

5\. Use a minimum of two runtime assertions per function.

6\. Restrict the scope of data to the smallest possible.

7\. Check the return value of all non-void functions, or cast to void to
indicate the return value is useless.

8\. Use the preprocessor sparingly.

9\. Limit pointer use to a single dereference, and do not use function
pointers.

10\. Compile with all possible warnings active; all warnings should then be
addressed before release of the software.

[1]
[https://yurichev.com/mirrors/C/JPL_Coding_Standard_C.pdf](https://yurichev.com/mirrors/C/JPL_Coding_Standard_C.pdf)

[2]
[https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Dev...](https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Developing_Safety-
Critical_Code)

~~~
taneq
A lot of these are pretty similar to the restrictions built into the IEC
61131-3 'Structured Text' programming language
([https://en.wikipedia.org/wiki/Structured_text](https://en.wikipedia.org/wiki/Structured_text)).
It's basically just removing things that commonly cause problems.

~~~
hoseja
To a great detriment to the expressive power of the language. How do you do
anything non-trivial without heap and function pointers?

~~~
sacado2
You can fly rockets without heap and function pointers, and that is definitely
non-trivial.

More precisely, however, heap allocation is usually accepted during the
initialization phase (the moment when you can still abort the process with no
consequence if needed, i.e in the case of a rocket, before it takes off).

~~~
lonelappde
In the realm of software, flying rockets is pretty simple. The hard parts of
flying rockets is not the software.

------
michaelt
The most inconvenient part about MISRA, for me, is the fact their stance is
open source tools can't state or paraphrase the rules [1] for copyright
reasons.

Which is why the writing of this blog post is so bizarre, telling you that
Rule 9 is pointless but not saying what Rule 9 is.

Admittedly the document is fairly priced at £10 per user - but good luck
getting a rule added into an open source project like clang analyzer when you
_can 't tell them what the rule is supposed to do_

cppcheck has been making an effort in this direction - giving you the unique
opportunity to back a kickstarter [2] that can't say what it's doing.

[1]
[https://www.misra.org.uk/forum/viewtopic.php?t=1189](https://www.misra.org.uk/forum/viewtopic.php?t=1189)
[2] [https://www.kickstarter.com/projects/3300446/add-all-
missing...](https://www.kickstarter.com/projects/3300446/add-all-
missing-10x-misra-rules)

------
humanrebar
Picking up one of these safety critical guidelines with the intent to raise
your own quality standards as an engineer or team is certainly a great idea.
There is a lot of thought put into these documents and it's likely there are
at least a few things you haven't thought about or perhaps you discount too
quickly.

That being said, this isn't a spec for good software. It's more of a spec for
auditing software that _has_ to work in a predictable way. The main consumers
for this are, yes, software engineers and managers, but it's especially useful
for framing quality assurance efforts.

It's entirely possible to check all the boxes while still cranking out swill.
For instance, I'd be surprised if the Volkswagen software that famously
assisted in cheating on emissions tests was properly MISRA reviewed since a
lot of the guidelines have to do with making sure the code does exactly what
is intended, no more or no less. A full review with someone who could read
code would either require the reviewer to ask "this is the code that cheats on
the test, right?" or to be oblivious as to the full purpose for the code.

~~~
ChrisRR
I agree with this point. The MISRA standard is mainly there to discourage use
of the parts of C that most often cause faults. You can comply to MISRA C
while ignoring some of the rules if you determine the risk to be justifiable.

Ideally, these un-safe methods would be removed from the C language, but then
that would be removing the low level ability from C that it is very suited
for. So these guidelines exist to note the most dangerous parts of C, but it
is still up to the developer to determine how to use it safely.

------
paulmd
> Rule 9: This precludes the use of a construct that is not supported by the C
> standard. As such it is a pointless rule.

I'm not sure that's true. Compilers (let's say, MSVC++) tend to support a
mismash of standards and de-facto standards. If you are forbidden from using a
construct not supported by the C standard (under which you are building) you
are in fact specifying _strict_ compliance with a _particular_ standard, which
is meaningful.

------
01100011
MISRA and other such standards are great places to start thinking about
reliability and safety. That said, I think there is a danger in believing that
code which complies with a certain set of standards is safe. Attempting to
bring non-safety code into compliance with MISRA may increase safety, but
safety, like security, is something that needs to be designed in, both to the
software and the overall system. Standards compliance is often just a CYA move
to avoid legal and financial liability. Often, trying to make a codebase
compliant with a standard like MISRA will reduce overall code quality as good
software design practices take a backseat to compliance metrics and QA
reports.

~~~
dognotdog
While many items in MISRA are sensible (some I do find quite
counterproductive, if code quality in terms of readability and maintainability
is also a concern), I have seen MISRA standards being applied to a legacy
embedded codebase with terrible effects. What was being done, for example, was
putting explicit typecasts everywhere a warning popped up respective
mismatched integer sizes or similar, instead of refactoring the code to
improve variable typing.

The best end result was largely unreadable code. Why? Because the junior
developers tasked with the MISRA compliance efforts were measured by reducing
the number of warnings instead of improving code quality.

The bonus was actual breakage in the field, as the test coverage of the legacy
code being converted was particularly abysmal. But not to worry, another
junior dev was tasked with creating unit tests for every function! With a
codebase unsuitable to unit testing through fuzzy interfaces, that effort was
about as effective as one would expect, too. </rant>

------
konstmonst
I think a lot of misra rules are bullshit and not account for improvements in
computer science.

\- goto is useful for error handling and when you have to double break

\- function pointers are useful and easy to read state machines and also for
functional programming, which is sometimes easier to comprehend and produces
better patterns

\- "Restrict functions to a single printed page." in my experience does not
work. I would rather partition functions by topic or by level of
"zoom"/abstraction

\- "Use a minimum of two runtime assertions per function." that doesn't really
say anything useful imho. Use as much as experience tells you too.

I agree with the rest

~~~
mhh__
I think your fourth rule is better stated along the lines of requiring
constraints on both input and output (Performance?)

a la

bool noNaNs(float[] test); bool isSorted(inout float[]); float[] sort(float[]
input) in(input.noNaNs) out(o; o.isSorted) { return input; }

Not sure about goto, I'm not sure what I prefer between goto or a while loop
and a very big switch statement (let's say) to implement a lexer.

------
MaxBarraclough
I was thinking recently about a related problem: suppose all I care about is
feeding my C compiler with code which is entirely free of undefined behaviour.
How would I do that?

MISRA C doesn't get me there - it _helps_ , but isn't enough to _guarantee_
the absence of undefined behaviour, despite its 'rule' to avoid UB [0] (which
is not mechanically verifiable). It would presumably be possible to use a
Turing-complete subset of C, defined such that compliance to it could be
verified automatically. I imagine such a subset might be awfully
claustrophobic, but my intuition is that this should be possible.

Another approach would be to write code in a different language entirely -
either one defined to be free of undefined-behaviour, or one where the absence
of it can practically be established statically/automatically. We could then
transpile to C code. The transpiler could then guarantee never to generate C
code with undefined behaviour.

It seems to be possible to do this today by writing Ada SPARK code and using
the (proprietary, terribly pricey) _CCG_ transpiler. [1] (SPARK is a fine
choice here. When programming in the SPARK subset, it's impossible to invoke
Ada's equivalent of undefined behaviour [0].)

Is there a 'tidier' answer to this problem, or perhaps something obvious that
I'm missing?

A related question: is there a 'tidy' way that I can be certain my C code is
insensitive to platform-specific behaviours (what C calls _unspecified_ ),
such as the evaluation-order of argument expressions?

[0]
[https://learn.adacore.com/courses/SPARK_for_the_MISRA_C_Deve...](https://learn.adacore.com/courses/SPARK_for_the_MISRA_C_Developer/chapters/07_undefined_behavior.html)

[1] [https://www.electronicdesign.com/industrial-
automation/artic...](https://www.electronicdesign.com/industrial-
automation/article/21807302/ada-compiler-generates-c-source)

------
carlmr
> Such issues are not important in machine generated code (because such code
> is never read by humans).

A does not imply B. There's often broken generated code that is read by
humans. Readability of generated code can be helpful and often essential, in
finding bugs.

~~~
clarry
Yep, sometimes we have to do without cushy debuggers and easy reproducibility
in a test environment. A registers dump and a top few stack items may very
well be all you have for figuring out a bug.

------
kick
I found this a while ago, after reading the guidelines and wanting to hear the
opinions of others on it. Interestingly, the reason I found out about them to
begin with was George Hotz during an interview going something like "I thought
MISRA guidelines were stupid but then I actually read them and like, these are
by really smart people, man!"

I just pulled it up and here's what he said in the interview ad verbatim:

 _" All of this code is Open Source, readable, and I believe now it's all
MISRA C-compliant, too."

Interviewer cuts in: "What's that mean?"

"Um, MISRA is like the automotive coding standard. At first I—you know, I've
come to respect—I've been reading, like, the standards lately, and I've come
to respect them, they're actually written by very smart people!"

[The interviewer says something irrelevant to the point here that I don't feel
like typing up and that Hotz didn't seem to agree with and that I don't really
agree with.]

"MISRA's written by, like, computer scientists. And you can tell by the
language they use—you can tell by the language they use, they talk about like
whether certain, uh, conditions in MISRA are decidable or undecidable, and I
and I and I...you mean like the halting problem? And, yes! Alright, you've
earned my respect, I will read carefully what you have to say, and we want to
make our code compliant with that."_

He obviously worded his praise a bit strangely, but a standard written well
enough to tame someone like George Hotz is fairly alluring. I was probably as
surprised as he was when I found out _how_ good they were. They set the bar so
high that very little matches it as far as technical writing goes.

~~~
taneq
No matter what else you think about the guy, he's certainly never shown any
signs of low self esteem. >.>

------
0xff00ffee
I downloaded the actual document and spent 10 minutes reading every 20th page.
This is a staggering effort of technical writing.

I feel like I'm reading "The Pact" from the Silo series of sci-fi (Wool,
Switch, Dust). Hopefully you get the reference.

This goes far beyond coding guidelines. It reads more like THINKING
guidelines, fallacies to decision making to resource allocation.

Who is the target audience for this?

~~~
pjc50
> This goes far beyond coding guidelines. It reads more like THINKING
> guidelines

Well, yes. That's the "safety culture" influence, the idea that there is not
really such a thing as an "accident". With careful thought all the possible
outcomes should be forseeable, and mitigation should be in place for all
risks. This includes what might be called affordances for the programmer -
tools that are prone to misuse and mistakes should be avoided. Guardrails
around thought.

This chafes if you got into programming for the freedom, but is a lot more
reassuring for people driving the car.

(edit: my own personal benchmark for technical writing is the dully-named "App
Note 47: High Speed Amplifier Techniques" by the legendary Jim Williams. From
its own preface:

"This publication represents the largest LTC commitment to an application note
to date. No other application note absorbed as much effort, took so long or
cost so much. ... We intend to supply useful high speed products and the level
of support necessary for their successful application(such high minded
community spirit is, of course, capitalism’s deputy)."

It is 132 pages including photographs, illustrations, screenshots of
osciliscopes, equations, and a few jokes.)

~~~
gmueckl
Safety critical systems aren't places that tolerate clever hacks for the sake
of being clever. But meeting application requirements while staying within the
safety guidelines can be an interesting challenge in its own right.

