Moving beyond C-language development with MISRA C++:2008 - Embedded.com

Moving beyond C-language development with MISRA C++:2008

MISRA C++:2008 wasfinally released on June 5, 2008, following 3 years of work by a groupof willing volunteers. They set out to craft a set of rules for thesafe use of C++ in critical systems and did so under a glare of publiccomment. But the roots of this new standard go much further back intime.

The C language has long been recognised in the embedded world asexpressive and hazardous, versatile yet ambiguous. There were manyefforts to curtail the language in its early days, but it was not untilpublication of the MISRA-C guidelines that theembedded software world realised the benefits of a language subset andcoding rule-set.

From its earliest definition stage, the C++ language adoptedstronger language definition than C had achieved, while yet it had toretain C as a compatible 'little brother'. It is a large language andearly 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 variousC++ language features, in both time and space terms. One could arguethat this endeavour, more than any other, eased the introduction of C++into embedded environments.

The business of creating standards for C++ has followed a similarpath to C: the language becomes quite stable and mature beforestandards become accepted and widespread. Early adopters are toofocussed on application suitability, language feature adoption, libraryusage and other considerations, to be concerned with safe use of theinherent language.

Notwithstanding, the high integrity C++ standard (HICPP) thatProgramming Research published in 2003 was the first public release ofa set of coding rules for C++, and these were extensively reviewed andadopted.

MISRA C++ began its deliberations in 2005, with group participationby various tool-vendors, including Programming Research (PRQA) as theonly representative from the ISO++ Working Group.

Input documents included the HICPP, a C++ coding standard fromLockheed Martin (JSF AV++), the MISRA C standard, an analysis of C++language vulnerabilities, and various other sources. The approach takenwas to assess every rule from a safety-case perspective, and rejectrules that did not meet that criterion.

Furthermore, each rule must be clear and unambiguous, have decentrationales, example code demonstrating positive and negative cases. Inaddition 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. Oneobjective of the standard is to adopt C++ idioms in preference to onesfound in C. This includes preference for the new C++ cast operationsand avoidance of function and variable macros.

The pre-processor is particularly interesting in this regard.Availing of the C++ language protection for type conversion throughfunction interfaces is a good safety rationale for prohibiting functionmacros 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: ++pevaluated 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 thelanguage. Template declarations, in particular, have a range of rulesfocussed on issues such as name lookup, construction, andinstantiations. A good example is the rule requiring explicit definition of a copy constructor alongside a template constructor, toprotect 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. Theset of rules covering the control-fl ow constructs (goto, continue, andbreak) are well-thought through. In certain circumstances continue andbreak can be used. S

Surprisingly (and bravely) goto is not explicitly banned, which is adeparture from the MISRA-C equivalent advice. While goto can indicatebadly constructed and incomprehensible logic and make testing difficult, any alternative in an acceptable context requires fl ag variablesand additional conditional logic, itself prone to confusion andmistake.

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 whenpassed through a function interface. In C++, this decay of typeinformation can be avoided in a number of ways.

<>void f1(int array[10]);            // index isredundant here ” param is ?int *'
void f2(int (&array)[10]);      // param has type: ref to array of 10ints

void bar ()
{
  int array[10];
  f1(array);                           // arraydecays to pointer
  f2(array);                           // array doesnot decay ” index preserved.
}

MISRA C++:2008 is a large standard, containing 228 rules. CodingStandard Enforcement (CSE) tools, such as QAMISRA for C++ from PRQA,are already available to help you to adhere to these rules and to meetthe MISRA C++:2008 coding standard, effectively and confidently.

The new standard contains important protections for the use of theC++ language and is worth inspecting for suitability in your owndevelopment environment, whether embedded or system, and whether safetyor mission-critical in nature

Fergus Bolger is Chief TechnicalOfficer at ProgrammingResearch (PRQA).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.