Many programmers these days, especially in
embedded, release needlessly complex code. While this code might
work, it is often far more complicated than it needs to be.
Complicated code tends to be problem-riddled code. There is a
saying that “code isn’t released, it is allowed
to escape.” There is a good reason for that saying; there
is an abundance of overly complex (that is, poorly written)
software inside embedded systems. Some of it, unfortunately, is
found in safety-critical applications, including important systems
in new generations of vehicles. This situation has led the Motor
Industry Software Reliability Association (MISRA) to step in with
some specific guidelines, presenting a challenge for
programmers.

Before we look at MISRA in some depth,
let’s focus on the basic problem: A lot of software is
written in a manner far more complex than it needs to be to do the
job. As programmers, we don’t set out to write complex
code; it just often comes out that way. It is simply the way the
human mind works as opposed to the structured, deterministic world
of computers.

But what is wrong with complex code especially
if it works? It has been found that complex software is problematic
software. Ewan Tempero, associate professor of The University of
Auckland who specializes in measuring software design quality, has
identified five problems with complex code:

1. It is harder to understand.

2. It is more likely to have a defect.

3. It is harder to change.

4. It takes longer to produce.

5. It is more difficult to reuse.

Tools are available

Fortunately, many commercially available tools
ranging from affordable to outrageously expensive can pore over
your code, make suggestions and recommendations, and even find
problems that don’t show up in live code testing. So the
question now becomes: Why do so many programmers not use these
readily available tools?

Example software-optimizing tools.

I can think of three reasons:

Schedule pressure: Just get the code
done and out. If it compiles and runs, test it and ship it. There
is no need to analyze working code.Fear of
uncertainty: Programmers are afraid of what analyzing the
code might reveal. The attitude is “these code analyzers
spit out so many problems with my code that it is unrealistic to
fix all that stuff.”Information
shortage: A few programmers might not be aware they need to
do code analysis or aren’t aware of the available tools.

The pervasiveness of poor-quality software has
spurred action on the part of various industries. In the case of C
and C++ software development, MISRA is the most notable. This
group, which includes companies such as Ford, Jaguar, and TRW, has
created a set of guidelines to improve the reliability of C and C++
software. Several of these guidelines are controversial, but, when
followed, will definitely produce a higher-quality product.

The MISRA guidelines

In my professional opinion, however, it is
impossible to write strictly MISRA-compliant C or C++ code. As you
get used to the guidelines, you can get better at it, but it is
almost mandatory to have a software tool that can check your code
for MISRA compliance. Fortunately, many are available that can do
just that.

The current MISRA C guidelines, MISRA-C:2004,
are composed of 122 mandatory and 20 advisory
“rules.” According to these guidelines, there
are several “language insecurities” relative to
the C language:

It is beyond the scope of this article to go
into the MISRA guidelines in depth, but the details outlined by the
MISRA-C:2004 guidelines relative to the above list make for
interesting reading.

One of the more interesting and controversial
rules, rule 20.4, states that “dynamic heap memory
allocation shall not be used.” OK. Remember that MISRA-C
and C++’s goal is “reliable” code.
This means “deterministic.” If you think about
it, if you statically allocate your memory, you are likely to avoid
things like memory leaks and memory exhaustion (both bad things).
This rule also states that you can’t use functions that
dynamically allocate memory. OK again. That means we have to know
whether a function we rely on calls calloc(), or malloc(), and
eliminate those calls.

Another controversial rule is 4.2, which states
that “trigraphs shall not be used.” Trigraphs
are sequences of three characters. The reason for this rule lies in
possible confusion with regard to the question-mark symbol used in
the trigraph. Trigraphs can easily be replaced with other code
expressions (like ifthen–else), which are significantly
less ambiguous.

As you look into MISRA-C and C++ you will find
that the MISRA group has expended a lot of time and brainpower into
coming up with these guidelines. As programmers, we can benefit
tremendously by studying them. In case you have to produce
MISRA-compliant code, but it is not possible to follow all the
rules, you can write an “exception explanation”
to the rule and attach it to the code. If the exception makes sense
to the “owner” of the code, it can still be
considered MISRA-compliant with exceptions. The link to the MISRA
website is www.misra.org.uk/.

Also note that adoption of the MISRA C and C++
guidelines is not limited to the automotive industry. This
methodology is being adapted in far-ranging, non-automotive
embedded applications, anywhere software quality improvement is
desired.

Other guidelines and tools

There are other specifications that aim to
improve software quality, most notably the IPA/SEC C language guide
to coding practices by the Software Engineering Centre of the
Japanese Information-Technology Promotion Agency. This
specification is like MISRA on steroids and draws on MISRA, but
adds many other disciplines aimed at improving reliability,
maintainability, and portability. (MISRA’s aim is only to
improve reliability.) The IPA/SEC C specifications can be found at
www.ipa.go.jp/english/sec/index.html.

As stated earlier, many tools do MISRA-C/C++
compliance checking. Some of these tools also check for IPA/SEC C
compliance. Perhaps the best value tool for software quality
checking and analysis is PC-lint for C/C++ from Gimpel Software (www.gimpel.com). It should be a
standard tool in all C / C++ programmers’ bag of tricks.
It is $389 for a one workstation license, so there is no excuse for
not using it on every source module you write. The
“bug-of-the-month” feature on their website is
great fun too.

Other “higher-end” tools
with a dizzying array of code-checking features are tools like
Fujitsu’s PGRelief, Programming Research QA-C, LDRA
TBVision, and Parasoft’s C++Test. Several compiler suites
include built-in MISRA code checking like Green Hills Software
Optimizing C Compilers and Altium’s Tasking compiler. The
bottom line is that using tools to perform code-quality analysis
and recommendations should be a part of every embedded system
programmer’s workflow. The benefits can be enormous. By
going through this process of studying and analyzing your software
after it is first written, you can increase its reliability,
portability, and maintainability. Don’t just let your
code “escape.” Check it, analyze it, test it.
■