The MISRA C++ Standard is poised to play an even more important role in software design.
MISRA C++:2008 was
finally released on June 5, 2008, following 3 years of work by a group
of willing volunteers. They set out to craft a set of rules for the
safe use of C++ in critical systems and did so under a glare of public
comment. But the roots of this new standard go much further back in
time.
The C language has long been recognised in the embedded world as
expressive and hazardous, versatile yet ambiguous. There were many
efforts to curtail the language in its early days, but it was not until
publication of the MISRA-C guidelines that the
embedded software world realised the benefits of a language subset and
coding rule-set.
From its earliest definition stage, the C++ language adopted
stronger language definition than C had achieved, while yet it had to
retain C as a compatible 'little brother'. It is a large language and
early attempts to restrict various features (the 'Embedded C++'
proposal) created a stir in the ISO C++ working group
(WG21), causing the production of a valuable document.
The 'C++ Performance Report' clarified the cost involved in various
C++ language features, in both time and space terms. One could argue
that this endeavour, more than any other, eased the introduction of C++
into embedded environments.
The business of creating standards for C++ has followed a similar
path to C: the language becomes quite stable and mature before
standards become accepted and widespread. Early adopters are too
focussed on application suitability, language feature adoption, library
usage and other considerations, to be concerned with safe use of the
inherent language.
Notwithstanding, the high integrity C++ standard (HICPP) that
Programming Research published in 2003 was the first public release of
a set of coding rules for C++, and these were extensively reviewed and
adopted.
MISRA C++ began its deliberations in 2005, with group participation
by various tool-vendors, including Programming Research (PRQA) as the
only representative from the ISO++ Working Group.
Input documents included the HICPP, a C++ coding standard from
Lockheed Martin (JSF AV++), the MISRA C standard, an analysis of C++
language vulnerabilities, and various other sources. The approach taken
was to assess every rule from a safety-case perspective, and reject
rules that did not meet that criterion.
Furthermore, each rule must be clear and unambiguous, have decent
rationales, example code demonstrating positive and negative cases. In
addition to 'Required' and 'Advisory', there is also a 'Document'
category for non-automatically enforceable rules.
Perhaps the best way to investigate the standard is by example. One
objective of the standard is to adopt C++ idioms in preference to ones
found in C. This includes preference for the new C++ cast operations
and avoidance of function and variable macros.
The pre-processor is particularly interesting in this regard.
Availing of the C++ language protection for type conversion through
function interfaces is a good safety rationale for prohibiting function
macros in favour of inline functions:
#define max(a,b) ((a>b) ? a : b)
// Wrong: macro
inline int32 maxf(int32 a, int32 b) // Correct:
inline function
{ return (a>b) ? a : b; }
y = max(++p,q);
// Wrong: ++p
evaluated twice
y = maxf(++p,q)
// Correct: ++p evaluated once and type
// checking performed (q is const)
The standard includes rules covering many advanced features of the
language. Template declarations, in particular, have a range of rules
focussed on issues such as name lookup, construction, and
instantiations. A good example is the rule requiring explicit defi
nition of a copy constructor alongside a template constructor, to
protect deep copy semantics.
struct A {
// A ( A const & )
// Wrong: copy constructor implicitly defined
template A (T & t) {
m_i = new int ();
*m_i = t.m_i;
}
int * m_i;
};
One area of likely contention is the rule regarding use of goto. The
set of rules covering the control-fl ow constructs (goto, continue, and
break) are well-thought through. In certain circumstances continue and
break can be used. S
Surprisingly (and bravely) goto is not explicitly banned, which is a
departure from the MISRA-C equivalent advice. While goto can indicate
badly constructed and incomprehensible logic and make testing diffi
cult, any alternative in an acceptable context requires fl ag variables
and additional conditional logic, itself prone to confusion and
mistake.
As a final example, we'll look at an issue common to C and C++ code.
Arrays exhibit the behaviour of reducing to an object pointer type when
passed through a function interface. In C++, this decay of type
information can be avoided in a number of ways.
<>
void f1(int array[10]);
// index is
redundant here " param is ?int *'
void f2(int (&array)[10]);
// param has type: ref to array of 10
ints
void bar ()
{
int array[10];
f1(array);
// array
decays to pointer
f2(array);
// array does
not decay " index preserved.
}
>
MISRA C++:2008 is a large standard, containing 228 rules. Coding
Standard Enforcement (CSE) tools, such as QAMISRA for C++ from PRQA,
are already available to help you to adhere to these rules and to meet
the MISRA C++:2008 coding standard, effectively and confidently.
The new standard contains important protections for the use of the
C++ language and is worth inspecting for suitability in your own
development environment, whether embedded or system, and whether safety
or mission-critical in nature
Fergus Bolger is Chief Technical
Officer at Programming
Research (PRQA).