C and C++ are by some distance the most widely used languages for embedded software development. Recent research by VDC shows C being used by 70% of the embedded systems companies surveyed and C++ by 42%. C has been implemented for virtually every processor. It provides a wide range of resources and libraries, and is supported by a wide range of tools.
The C language, in particular, allows the developer to do many things which are essentially incorrect. It is all too easy to write code which conforms to the language standard but which will result in either program failure (i.e. a crash) or undefined behaviour. Common examples are code which results in accessing memory outside the bounds of an array or an arithmetic operation which results in integer overflow.
Author: Fergus Bolger, CTO Programming Research Ltd
The Philosophy of Coding Standards
The industry-accepted way to tackle these hazards is to adopt a Coding Standard. In their simplest form, coding standards define a set of consistent coding practices. Although uniformity of style can be valuable within a software project, they do not address the important attributes of software quality such as reliability, portability or maintainability. The more fundamental role of coding standards is to define a safer sub-set of the programming language by framing a set of rules which eliminate coding constructs known to be hazardous.
The MISRA coding guidelines, embodying this principle of safe sub-setting, are now accepted world-wide as the benchmarks for developing safety-critical software in C and C++. They have been widely accepted because they are concise and readable and because they focus on essential issues. A very recent poll (Ganssle, 2014) of 500 respondents revealed some interesting data on coding standard adoption rates. The main finding suggested that about 60% of all coding standards in use are MISRA-based. The strictness of adoption was another interesting finding, with MISRA-based coding rule sets achieving 75% consistent use within the development team, whereas other rule sets achieved less than 50%.
The Principle of Deviation
MISRA coding standards contain widely respected guidelines for developing in C and C++ languages. These guidelines focus on issues which are important when developing critical software systems. MISRA also recognizes that, in some situations, it is unreasonable or even impossible to comply with a coding guideline and that it is necessary to deviate from certain rules. A deviation states the reason for not complying with a particular coding rule in a certain circumstance. It also provide a rationale and description of the extent to which the particular rule is being relaxed, and supplies a properly constructed safety case that includes mitigation against the effects of not complying.
However, in the absence of a carefully stated scope for the non-compliance, a basic deviation facility could be misunderstood or abused and ultimately undermine the efficacy of the guidelines.
Constraining the Use of Deviations
In the same way that coding standards themselves need objective creation and well-understood rationales, the reasons given for deviating from coding rules similarly need a common expression and agreed interpretation and a precise scope for their application. The automotive industry, the original and still leading application domain for MISRA, has faced up to this requirement. Both MISRA itself and one national body, the Japanese Automotive Manufacturers Association (JAMA), have each begun the process of setting out the conditions under which to permit specific deviations from full MISRA compliance.
The thrust of this work is to define a set of rule deviations that are tightly constrained in scope. An important first stage is to categorize the broad reasons for deviation from rule non-compliance.
Categorizing Deviation Reasons
By breaking deviations down into the following categories, the practical difficulties with compliance are made more apparent. Additionally, this categorisation guards against inappropriate deviation and weakening of the coding standard intent.
a) Performance: It may seem strange and non-intuitive to suggest performance as a reason for not following good coding practice, but the following real-life situation demonstrates the need:
As part of the vehicle’s engine control system, a timing variable needs to be accumulated at regular intervals. The code, correctly formulated to meet MISRA-C:2012 Rule 10.6 (value not to be assigned to a wider type), reads:
extern uint16_t qty, time_step;
uint32_t prod = ( uint32_t ) qty * ( uint32_t ) time_step;
The casts ensure that the 16-bit operands will not overflow in the 32-bit multiplication for this compiler. However, the compiler performs this operation using “shift and add” mode of long multiplication rather than the IMUL (signed multiplication) mode it is equipped with. The compiler vendor has clarified that IMUL mode only occurs on implicit conversion, requiring the expression to read:
uint32_t prod = qty * time_step; // deviate from Rule 10.6
By permitting implicit conversion in this case, the single clock cycle IMUL operation is guaranteed, rather than the ~100 clock cycle worst case execution of the former, thus justifying a controlled deviation on the basis of performance.
b) External (third-party) code: This category includes common libraries, auto-generated code, and legacy internal code modules or even just a complex function encompassing a key application algorithm. Maintainers of public-domain libraries, given their broad application domain, rarely have the motivation to comply with MISRA or other coding standards. Auto-generated code, unless it meets a functional safety standard like ISO 26262, will likely contain inherent MISRA violations. Legacy code may pre-date the project’s adoption of MISRA. The impact analysis of possible refactoring to meet MISRA rules may itself raise a concern. The safety case in all these situations is based on “qualified through use” reliance in combination with specific other quality measures.
c) Build Configurations: A particular feature of automotive supplier applications is to provide many variants of a single code-base according to customer need. Rather than build-level control of this delivery, configuration mechanisms are deployed to control feature delivery for each variant. As a result, MISRA compliance can suffer in terms of redundant code, invariance in expressions, and related global issues.
d) Access to Hardware: In order to access registers, address absolute memory and control interrupts, embedded developers need access to compiler-specific extensions to the C language, resulting in MISRA non-compliance. The safety case will typically require careful unit test coverage.
e) Defensive Coding: Given the absence of robust exception-handling in C, defensive coding practices may involve, for example, programmatic guards against unforeseen behaviour. A fully capable analysis tool will correctly detect invariant conditions and unreachable code as a result. The safety case must involve forced unit test execution of these paths or conditions.
f) Language Features: There are valid code quality reasons to use ‘recent’ language constructs, for example Boolean or ‘long long’ types or inline functions. However, these can require deviation from older versions of MISRA. The safety issue is that even 15-year old C99 constructs are not guaranteed to be supported by all compilers.
Structure of Controlled Deviation
Categorisation of the different rationales is a first step in creating a properly constrained deviation structure. This leads naturally into an elaboration of all specific known deviation cases, by rule and by category. MISRA and JAMA are both documenting, with industry participation, documenting a set of rule scope restrictions, each with detailed justification and safety case. Even outside of an automotive context, these initiatives are important. The MISRA coding standard was originally designed for the automotive sector, but from its early years it found willing adoption in many other embedded environments, from consumer products to medical devices, industrial control to EDA. Equally, the establishment of a controlled deviation structure is important in any industry or organisation adopting coding standards.
Automated Tool Support
A coding standard without an automated means of enforcement and a rich audit and reporting capability will soon become a bookcase adornment, rarely referenced or followed. The starting point for a competent automated static analysis tool must be accuracy in its diagnostic output, clarity of comprehension and explanation on each issue raised, and detailed reporting against every version of the software project.
But even an environment of automated tool enforcement needs awareness and application of an approved deviation policy, especially since this removes one impediment to full compliance. Both the coding rules and the deviation policy must be convenient for developers, trusted by leads and managers, and facilitate detailed QA reporting.
A basic deviation system will couple each instance of rule suppression to its supporting deviation, and preserve this coupling through the lifetime of the relevant source code. The requirements are more complex when dealing with controlled deviations. Any suppression of the relevant coding rules must obey the tighter restrictions in force, and no suppression may take place outside of that controlled set of deviations. When choosing the specific code location where a reported diagnostic is to be suppressed, developers must be constrained to only suppress using the permitted range of controlled deviations.
The MISRA C coding standards are synonymous with safe and defensive use of C in many embedded environments and beyond. Being both comprehensive and wide-ranging in the restricted use of the C language, a system of controlled deviation is now recognized as a necessity, as exemplified by various industry and community efforts to specify such curtailment. In this article, we have explored the categories of deviation, and seen how legitimate specific reasons for deviation are now being crafted for industrial use. Sophisticated and automated tooling support for the controlled deviation initiative along with reporting and other elements of a compliance solution are available today.
Ganssle, J. (2014, August 4).
Retrieved from The Ganssle Group: www.ganssle.com/tem/tem266.html
About the Author
Fergus Bolger is CTO of Programming Research Ltd. He received his B.E. and Masters of Engineering from University College Dublin. He can be reached at firstname.lastname@example.org
PRQA’s relationship with MISRA stretches back some 20 years. Major elements of both the MISRA-C and MISRA-C++ guidelines have been derived from our own coding standards and our technical experts remain as key members of the MISRA-C and MISRA-C++ working groups. PRQA static analysis tools, QA·C and QA·C++, are at the forefront in delivering MISRA-C and MISRA-C++ compliance checking as well as a host of other valuable analysis capabilities. For more information go to:
Programming Research Ltd