CODE: MISRA C and C++ — Safety Standards for Critical Systems

MISRA (Motor Industry Software Reliability Association) defines coding standards for C and C++ that are mandatory in safety-critical industries. Understanding MISRA's philosophy — processor independence, portability, and predictable behavior — is essential for automotive, aerospace, and medical embedded software engineers.

When software controls a vehicle's brakes, an aircraft's flight surfaces, or a medical infusion pump, a software bug is not an inconvenience — it is a potential fatality. MISRA (Motor Industry Software Reliability Association) was created to define a subset of C and C++ that eliminates the most dangerous and unpredictable language features, making safety-critical code analyzable, portable, and correct.


What Is MISRA?

MISRA stands for the Motor Industry Software Reliability Association. It is a consortium of automotive manufacturers, component suppliers, and engineering consultancies that was established in the UK in the 1990s.

MISRA publishes coding guidelines for C and C++ that restrict the use of language features that are known to cause unpredictable, unsafe, or non-portable behavior. These guidelines have been adopted far beyond the automotive industry:

IndustryApplication
AutomotiveECUs, ABS, airbag controllers, ADAS
AerospaceFlight management, avionics
MedicalInfusion pumps, monitors, pacemakers
IndustrialPLCs, robotics, safety controllers
DefenseWeapons systems, navigation

The Core Problem MISRA Addresses

The C programming language is powerful and portable, but it contains numerous features that introduce undefined behavior, implementation-defined behavior, and unspecified behavior. In safety-critical systems, these are unacceptable because:

  • The program may behave differently on different compilers
  • The program may behave differently on different hardware architectures
  • The program may produce unpredictable results that cannot be statically analyzed
  • The compiler is free to do anything — including deleting safety checks — when undefined behavior is present

MISRA identifies and restricts these problematic features.


Key Design Principles

Processor Independence

MISRA C code must not contain any assumptions about the underlying processor architecture. This means:

c
// BAD: Assumes int is 32-bit (not guaranteed by C standard)
int sensor_value = read_sensor();

// GOOD: Explicit size regardless of platform
int32_t sensor_value = read_sensor();

Standard C types like int and long have sizes that depend on the platform and compiler. MISRA requires using the fixed-width types from <stdint.h> (C99) or <cstdint> (C++) to eliminate this ambiguity.

Portability

MISRA code must compile and behave identically across any conforming implementation. Compiler-specific extensions, non-standard pragmas, and implementation-defined behavior are restricted or forbidden:

c
// BAD: GNU extension, not portable
int bits = __builtin_popcount(x);

// GOOD: Portable implementation
int count_bits(uint32_t x) {
    int count = 0;
    while (x) { count += x & 1; x >>= 1; }
    return count;
}

Analyzability

MISRA code must be amenable to static analysis — automated tools that can prove properties about the code without running it. Many MISRA rules exist specifically because the restricted code pattern is difficult or impossible to analyze statically.

For example, MISRA restricts:

  • Dynamic memory allocation (unpredictable fragmentation)
  • Recursion (stack depth cannot be bounded statically)
  • Multiple exit points in functions (complicates flow analysis)
  • goto (disrupts structured control flow)

MISRA C Versions

VersionYearFocus
MISRA C:19981998First release, automotive focus
MISRA C:20042004Expanded rules, wider adoption
MISRA C:20122012C99 support, mandatory/advisory/required distinction
MISRA C:20232023C11 and C17 support, updated rule set

MISRA C++ Versions

VersionYear
MISRA C++:20082008
MISRA C++:20232023

Rule Categories

MISRA C:2012 classifies rules into three categories:

text
MISRA Rule Categories:
+-------------------+--------------------------------------------------+
| Mandatory         | Must be followed. No deviation permitted.        |
|                   | Violation is a hard error.                       |
+-------------------+--------------------------------------------------+
| Required          | Must be followed unless a formal deviation       |
|                   | process is completed and documented.             |
+-------------------+--------------------------------------------------+
| Advisory          | Should be followed. Informal justification       |
|                   | needed if violated.                              |
+-------------------+--------------------------------------------------+


Examples of MISRA Rules

Memory and Types

Rule: Use explicit type widths from <stdint.h>

c
// Non-compliant: int size is platform-dependent
int counter = 0;

// Compliant: explicit 32-bit signed integer
int32_t counter = 0;

Rule: Do not use dynamic memory allocation

c
// Non-compliant: malloc/free forbidden in safety-critical code
uint8_t *buffer = (uint8_t *)malloc(256);
// ... use buffer ...
free(buffer);

// Compliant: static or stack allocation
static uint8_t buffer[256];

Dynamic memory allocation is banned because:

  • Fragmentation can cause allocation to fail at unpredictable times
  • Memory leaks are possible
  • Heap behavior is difficult to analyze statically

Control Flow

Rule: No recursion

c
// Non-compliant: recursive function (stack depth unbounded)
uint32_t factorial(uint32_t n) {
    if (n == 0) return 1;
    return n * factorial(n - 1);
}

// Compliant: iterative implementation
uint32_t factorial(uint32_t n) {
    uint32_t result = 1u;
    uint32_t i;
    for (i = 1u; i <= n; i++) {
        result *= i;
    }
    return result;
}

Rule: No goto

c
// Non-compliant: goto disrupts structured flow
if (error) goto cleanup;

// Compliant: structured error handling
if (error) {
    cleanup();
    return ERROR_CODE;
}

Rule: All switch cases must have a default

c
// Non-compliant: missing default
switch (state) {
    case STATE_INIT: init(); break;
    case STATE_RUN:  run();  break;
}

// Compliant: explicit default
switch (state) {
    case STATE_INIT: init(); break;
    case STATE_RUN:  run();  break;
    default: handle_error(); break;
}

Expressions and Operators

Rule: Avoid implicit conversions

c
// Non-compliant: implicit narrowing
uint32_t a = 1000u;
uint8_t b = a; // truncation — potential data loss

// Compliant: explicit cast with awareness of range
uint8_t b = (uint8_t)(a & 0xFFu); // explicit, with masking

Rule: Operands of bitwise operators must be unsigned

c
// Non-compliant: shifting signed type
int16_t x = 1;
int16_t y = x << 3; // behavior undefined for signed types

// Compliant: use unsigned types for bit manipulation
uint16_t x = 1u;
uint16_t y = (uint16_t)(x << 3u);


The Development Process with MISRA

Implementing MISRA compliance is a process, not just a coding style:

text
MISRA Compliance Process:
+-------------------+
| Requirements      |
+-------------------+
         |
         v
+-------------------+
| Coding Standard   |  <-- MISRA rules enforced here
| (MISRA C/C++)     |
+-------------------+
         |
         v
+-------------------+
| Static Analysis   |  <-- Tools: PC-lint, LDRA, QAC, Polyspace
| Tool Run          |
+-------------------+
         |
         v
+-------------------+
| Code Review       |  <-- Human review of rule violations
+-------------------+
         |
         v
+-------------------+
| Deviation Process |  <-- Formal documentation of rule exceptions
+-------------------+

Static Analysis Tools for MISRA

ToolVendor
PC-lint PlusGimpel Software
LDRA TestbedLDRA
QA C/C++Perforce (Helix QAC)
PolyspaceMathWorks
IAR C-STATIAR Systems
CoveritySynopsys

MISRA and Functional Safety Standards

MISRA C/C++ compliance is often required by higher-level functional safety standards:

StandardDomainRelationship to MISRA
ISO 26262AutomotiveRecommends MISRA C for software
IEC 61508IndustrialReferences MISRA as best practice
DO-178CAerospaceRequires similar coding standards
IEC 62443CybersecurityCompatible with MISRA practices

When a project must achieve ASIL D (the highest automotive safety integrity level), MISRA C:2012 compliance is essentially mandatory.


Conclusion

MISRA C and C++ are not arbitrary restrictions — they are carefully researched guidelines that eliminate the C/C++ language features most responsible for safety-critical failures. By enforcing processor independence, portability, and analyzability, MISRA-compliant code is not just safer; it is also easier to maintain, test, and certify.

For engineers working in automotive, aerospace, medical, or industrial embedded systems, understanding MISRA is not optional. It is a fundamental professional competency that directly determines whether the software you write can be used in products that people's lives depend on.