C++ for Safety-Critical Systems

Similar documents
C++ for Safety-Critical Systems. DI Günter Obiltschnig Applied Informatics Software Engineering GmbH

MISRA-C:2012 Standards Model Summary for C / C++

The programming language C. sws1 1

Chapter 5 Names, Bindings, Type Checking, and Scopes

C++ INTERVIEW QUESTIONS

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Top 10 Bug-Killing Coding Standard Rules

C++ Programming Language

The C Programming Language course syllabus associate level

How To Port A Program To Dynamic C (C) (C-Based) (Program) (For A Non Portable Program) (Un Portable) (Permanent) (Non Portable) C-Based (Programs) (Powerpoint)

Applied Informatics C++ Coding Style Guide

Simulink Modeling Guidelines for High-Integrity Systems

JOINT STRIKE FIGHTER. December 2005

SHIELDS UP! DEFENDING SOFTWARE AGAINST SAFETY & SECURITY RELATED PROGRAMMING ERRORS

Sources: On the Web: Slides will be available on:

How Safe does my Code Need to be? Shawn A. Prestridge, Senior Field Applications Engineer

Semantic Analysis: Types and Type Checking

Object Oriented Software Design II

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

El Dorado Union High School District Educational Services

Bachelors of Computer Application Programming Principle & Algorithm (BCA-S102T)

Symbol Tables. Introduction

1 Abstract Data Types Information Hiding

C Programming. for Embedded Microcontrollers. Warwick A. Smith. Postbus 11. Elektor International Media BV. 6114ZG Susteren The Netherlands

Software in safety critical systems

Course Name: ADVANCE COURSE IN SOFTWARE DEVELOPMENT (Specialization:.Net Technologies)

MSP430 C/C++ CODE GENERATION TOOLS Compiler Version 3.2.X Parser Error/Warning/Remark List

The Embedded C Extension to C

C++ Language Tutorial

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority)

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

PL / SQL Basics. Chapter 3

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

Programming languages C

Moving from CS 61A Scheme to CS 61B Java

Java Interview Questions and Answers

Fast Arithmetic Coding (FastAC) Implementations

Parameter passing in LISP

A C Test: The 0x10 Best Questions for Would-be Embedded Programmers

Ed. v1.0 PROGRAMMING LANGUAGES WORKING PAPER DRAFT PROGRAMMING LANGUAGES. Ed. v1.0

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

5 Arrays and Pointers

Object-Oriented Design Lecture 4 CSU 370 Fall 2007 (Pucella) Tuesday, Sep 18, 2007

A Static Analyzer for Large Safety-Critical Software. Considered Programs and Semantics. Automatic Program Verification by Abstract Interpretation

vector vec double # in # cl in ude <s ude tdexcept> tdexcept> // std::ou std t_of ::ou _range t_of class class V Vector { ector {

Multichoice Quetions 1. Atributes a. are listed in the second part of the class box b. its time is preceded by a colon. c. its default value is

Computer Programming I

Curriculum Map. Discipline: Computer Science Course: C++

Embedded Systems Conference April 3-7, San Jose [ESC-447] Safety-Critical Design Techniques for Secure and Reliable Systems

Pemrograman Dasar. Basic Elements Of Java

Programming languages - C - Extensions to support embedded processors

Keywords are identifiers having predefined meanings in C programming language. The list of keywords used in standard C are : unsigned void

Chapter 24 - Quality Management. Lecture 1. Chapter 24 Quality management

Objectif. Participant. Prérequis. Remarque. Programme. C# 3.0 Programming in the.net Framework. 1. Introduction to the.

Keil C51 Cross Compiler

Embedded Software Development with MPS

13 Classes & Objects with Constructors/Destructors

Lecture 2. Binary and Hexadecimal Numbers

Advanced Encryption Standard (AES) User's Guide

Instruction Set Design

Static Analysis of Dynamic Properties - Automatic Program Verification to Prove the Absence of Dynamic Runtime Errors

Object Oriented Programming With C++(10CS36) Question Bank. UNIT 1: Introduction to C++

Java technology trends offer renewed promise for portable embedded applications

1/20/2016 INTRODUCTION

Instruction Set Architecture (ISA)

Ada 2005 The GNAT Pro Company

Handout 1. Introduction to Java programming language. Java primitive types and operations. Reading keyboard Input using class Scanner.

IS0020 Program Design and Software Tools Midterm, Feb 24, Instruction

Characteristics of Java (Optional) Y. Daniel Liang Supplement for Introduction to Java Programming

An Overview of Java. overview-1

An Incomplete C++ Primer. University of Wyoming MA 5310

Chapter 7 Accessing Microcontroller Registers

Object Oriented Software Design

sys socketcall: Network systems calls on Linux

Adding Alignment Support to the C++ Programming Language / Wording

How to simplify software development with high level programming languages? Pierre-Alexandre Voye - ontologiae@gmail.com

Lecture 22: C Programming 4 Embedded Systems

9 Control Statements. 9.1 Introduction. 9.2 Objectives. 9.3 Statements

Language Evaluation Criteria. Evaluation Criteria: Readability. Evaluation Criteria: Writability. ICOM 4036 Programming Languages

Coding conventions and C++-style

Guide to SQL Programming: SQL:1999 and Oracle Rdb V7.1

Binary storage of graphs and related data

İSTANBUL AYDIN UNIVERSITY

#820 Computer Programming 1A

MPLAB TM C30 Managed PSV Pointers. Beta support included with MPLAB C30 V3.00

How To Write Portable Programs In C

Glossary of Object Oriented Terms

Operator Overloading. Lecture 8. Operator Overloading. Running Example: Complex Numbers. Syntax. What can be overloaded. Syntax -- First Example

VB.NET Programming Fundamentals

TOP 3 STRATEGIES TO REDUCE RISK IN AUTOMOTIVE/IN-VEHICLE SOFTWARE DEVELOPMENT

Fundamentals of Java Programming

OpenGL ES Safety-Critical Profile Philosophy

Object Oriented Software Design

Embedded C Programming, Linux, and Vxworks. Synopsis

C++FA 3.1 OPTIMIZING C++

CS 111 Classes I 1. Software Organization View to this point:

AppendixA1A1. Java Language Coding Guidelines. A1.1 Introduction

C++ Overloading, Constructors, Assignment operator

Transcription:

C++ for Safety-Critical Systems Günter Obiltschnig Applied Informatics Software Engineering GmbH St. Peter 33 9184 St. Jakob im Rosental Austria guenter.obiltschnig@appinf.com Abstract. C++ is now widely used in the development of software for embedded systems, even safety-critical and hard-real-time systems. Even if, due to their design, other programming languages may be better suited for the development of safetycritical systems, there are other relevant factors in favor of C++. Examples are availability of skilled developers and tool support. The use of C++ in the development of air vehicle software for the Joint Strike Fighter (JSF), and the public release of the C++ coding standard used in that project (JSF C++), has certainly increased the interest in using C++ for safety-critical systems. In June 2008 the MISRA C++ standard "Guidelines for the use of the C++ language in critical systems" has been released by the Motor Industry Software Reliability Association. Similar to the JSF C++ standard, the MISRA C++ standard defines rules, as well as a "safe" subset of the C++ language for the development of safety-critical systems. This paper gives an overview of both the JSF C++ and MISRA C++ standards and also looks in detail at some of their rules and the rationale behind them. An interesting aspect that is covered is also where both standard differ. For example, JSF C++ does not allow the use of C++ exceptions at all, whereas MISRA C++ specifies detailed rules for their use. 1 Introduction C++ [1] is now widely used in the development of software for embedded systems, even safety-critical and hard-real-time systems. It must be stated, though, that C++ (as well as C) is, by its design, not really a suitable language for writing high integrity or safety-critical software. C++ gives a programmer a great deal of freedom. With freedom comes responsibility, though, and, in the case of C++, a whole lot of responsibility. Nevertheless, there are good reasons for using C++ in a safety-critical system: Higher abstraction level. C++ allows for a higher level of abstraction than C, making it more appropriate for increasingly complex applications. At the same time, C++ allows low-level programming required for hardware access or high-performance code. Support for object-oriented programming. C++ directly supports object-oriented programming, which is the paradigm of choice in today s software development projects. Portability. Wide availability of C++ compilers for almost all hardware platforms enables easier porting of applications to new or lower-cost processors at any stage in a project. Efficiency. C++ compilers can generate code that performs as efficient, or even more efficient, than C code.

Availability of skilled developers. C++ is one of the most widely used programming languages, and a lot of skilled C++ developers are available. Tool support. Many tools that support model-driven development can automatically generate C++ code. Maturity. C++ is mature and consequently well-analyzed and tried in practice. On the other hand, C++ has a lot of issues that limit its suitability for safety-critical systems: C++ is a highly complex language. Learning and fully understanding C++ requires a huge learning effort. C++ code does not always do what one would intuitively expect from looking at the source code. At the same time, the high complexity of C++ increases the probability of compiler errors. C++ compiler writers are only humans, after all. The semantics of some C++ constructs are not fully specified, leaving room for portability issues the behavior of a program may vary depending on what compiler was used (undefined, unspecified and implementation-defined behavior). C++ makes it very easy for a programmer to make mistakes that cannot be diagnosed by a compiler (e.g., the use of the assignment operator = instead of the comparison operator == ). C++ does not provide any built-in run-time checking, e.g. for arithmetic overflows or array bound errors. While being a strongly-typed language, C++ leaves too many holes to circumvent the type system, deliberately or unintentionally. When using C++ for safety-critical systems, great care must be taken to avoid any language constructs and code that can potentially lead to unintended program behavior. C has most of these issues as well, though, and this hasn t stopped C becoming one of the most widely used languages in safety-critical systems. This has only been possible through the introduction of coding standards that limit language features to a safe subset that can be used without giving rise to concerns. 2 Coding Standards The most popular coding standard for using C in safety-critical systems is MISRA-C: Guidelines for the use of the C language in critical systems [2]. First published in 1998 and revised in 2004, MISRA-C specifies a safe subset of the C language in the form of 121 required and 20 advisory rules. MISRA-C has enjoyed great adoption among developers of safety-critical applications, not just in the automotive industry, at which it was initially targeted. MISRA-C has also had a great influence on another coding standard for using C++ in safety-critical systems. The Joint Strike Fighter Air Vehicle C++ Coding Standards for the System Development and Demonstration Program [3], or JSF C++ in short, was kind of revolutionary, as it signaled a move away from Ada as the mandated programming language for avionics software by the US Department of Defense. JSF C++, while taking many rules from MISRA-C, is a bit different in concept from MISRA-C (and the new MISRA-C++) as it also defines coding style and metric guidelines, which the MISRA standards don t have. For example, AV Rule 1 requires that [a]ny one function (or method) will contain no more than 200 logical source lines of code, and AV Rule 50 requires that [t]he first word of the name of a class, structure, namespace, enumeration, or type created with typedef will begin with an uppercase letter. All others letters will be lowercase. In total, JSF C++ defines 221 rules. The current trend to move from C to C++ in the development of critical systems has lead to the publication of MISRA-C++ [4] in the summer of 2008. MISRA-C++ takes many rules from MISRA-C: 2004 and adds many more C++ specific rules, bringing it to a total of 228 rules.

3 Issues with C++ in Safety-Critical Systems An analysis of MISRA-C++ and JSF C++ reveals many issues that must be taken great care of when using C++ in a safety-critical system. Some of these issues are briefly discussed in the following. Preprocessor Use of the preprocessor is strongly restricted by coding standards. Basically the only allowed use of the preprocessor is to implement include guards, preventing multiple inclusion of the same header file. 1 Other uses of macros, e.g. to define constants or to define inline macros are forbidden. Generally, C++ provides better alternatives for most uses of preprocessor macros. For defining constants, C++ supports the const keyword, as well as enumerations. Inline functions are a much better alternative than inline macros, avoiding all of the problems associated with functional macros and macro arguments. Implementation-defined, unspecified and undefined behavior The C++ standard specifies the exact (required) behavior for most, but not for all language elements. Certain language constructs are described as implementation-defined, unspecified or undefined. Implementation-defined means that the compiler writer is free to implement a certain language construct in any way he sees appropriate, as long as the exact behavior is consistent, documented, and the compilation succeeds. The standard may specify a number of allowable behaviors from which to choose one, or it may leave it entirely up to the compiler writer. Unspecified is similar, except that the behavior of the implementation need not be documented and need not even be consistent. Undefined behavior means that the standards does not place any requirements whatsoever on the implementation. The compiler may even fail when compiling such a language construct, or the program may silently produce incorrect results. MISRA-C++ also defines the notion indeterminate, which specifies undefined behavior arising due to an omission in the C++ standard. Code that relies on implementation-defined, unspecified or undefined behavior is not portable, and thus forbidden by coding standards. The same applied to code using proprietary compiler extensions. Error-prone language constructs C++ allows many constructs that can easily lead to erroneous code. Examples are switch statements, where coding standards restrict the placement of case labels and require a break (or throw) to terminate every non-empty switch-clause, as well as a default case. For if, else, switch, which, for and do while statements, the body must be a compound statement, with the exception of else being followed immediately by another if. All if else constructs shall be terminated with an else clause. Restrictions are placed on the use of null statements (single semicolons). The use of for loops is also guarded by rules covering the use of loop counters, control variables, etc. Use of the goto statement is strongly restricted; setjmp/longjmp is forbidden at all. 1 Some compilers also provide proprietary mechanisms to prevent multiple inclusion of a header file (in the form of #pragma directives), but these are not allowed by MISRA-C and JSF C++.

Type System The type system in C++ has many loopholes that make it easy to circumvent it. Coding standards severely restrict the use of implicit or explicit type conversions (casts), as these can easily lead to a loss of information. The C++ standard does not define fixed sizes for built-in types, making it harder to write portable code requiring fixed-size integers, for example. In addition, C++ (as well as C) does all arithmetic operations in either int or long, depending on the original operand types. Prior to an arithmetic operation, integral types (signed/unsigned short and signed/unsigned char) are promoted to int. This can easily lead to non-portable code, as the following example shows: short i = 10000; short j = 8; int32 result = i * j; On a system where int is 32 bits (and short is 16 bits), the result will be as 80000, as one would expect considering that the multiplication is carried out with both operands promoted to int. However, on a system where int is just 16 bits, the result will be undefined, as the multiplication will be carried out in 16-bit, will thus overflow, and only the (wrong) result will then be converted to int32. The plain char type is problematic, as it can be either signed or unsigned. In C++, char, unsigned char and signed char are all distinctive types. Coding standards only allow the use of the plain char type for holding character values and forbid the use of the plain char type for arithmetic operations, as this leads to non-portable code. Classes Coding standard put a strong focus on encapsulation, meaning that member variables of a class must generally be private, and any undesired access to member variables (e.g., though a member function returning a non-const pointer a reference to it) must be prevented. Multiple inheritance should be avoided, with the exception of using multiple interface classes (classes only having pure virtual member functions as members) as base classes. Special care is required when dealing with compiler-generated default constructors and assignment operators. Dynamic Memory Use of dynamic or heap memory (new, delete) is generally strongly restricted in safetycritical systems. 4 A Comparison of MISRA-C++ and JSF C++ From a C++ developer s perspective, a comparison of MISRA-C++ and JSF C++ is a rewarding exercise, as it shows some interesting similarities, differences and even conflicts between the two standards and sharpens the eye for any potential issues arising out of the use of C++ in safety-critical systems. MISRA-C++ and JSF C++ have common roots in MISRA-C. MISRA-C++ takes many rules from MISRA-C, as does JSF C++. Another thing that both standards have in common is their dislike for macros, basically only allowing the use of macros for include guards, while at the same time making the use of include guards in header files mandatory. Both standards require the use of defensive programming techniques (run-time checks) and recommend the use of static analysis tools (MISRA-C++ Rule 0-3-1, AV Rule 15). There are a lot of common sense rules (e.g., avoiding stupid names, always initialize variables, etc.), where both standards agree as well. MISRA-C++ does not have any rules or guidelines regarding coding style or metrics. In the introductory text however, the authors of MISRA-C++ recommend the selection of an

appropriate coding styleguide. In contrast, JSF C++ has specific rules for coding style and software metrics (e.g., AV Rules 1, 3, 41 45, etc.). MISRA-C++ and JSF C++ disagree in a number of issues. For example, JSF C++ does not allow the use of C++ exceptions 2, while MISRA-C++ allows it. When dealing with null pointers, MISRA-C++ enforces the use of a NULL macro, whereas JSF C++ discourages use of the NULL macro and suggests the use of literal zero (0) instead. 5 Other Recommendations C++ provides many facilities that make writing correct and robust code easier. Although coding standards do not explicitly enforce or recommend the use of these facilities, their use can generally be recommended. For example, the RAII (Resource Acquisition Is Initialization) 3 idiom helps in implementing correct management of resources. RAII enables the implementation of smart pointers, which help to avoid many pointer-related errors 4. RAII also enables the implementation of scoped locks that greatly simplify the correct implementation of critical sections. Another important facility for writing robust C++ code are templates, as they enable the implementation of bounds-checked arrays. An interesting use for templates in safety-critical systems is the implementation of fixed-point arithmetic. When using exceptions, a C++ developer should be familiar with the concept of exception safety [5]. Exceptions greatly simplify error handling in programs. However, an exception in the wrong place can easily lead to objects or data structures left in an invalid state, causing trouble at a later time. Again, RAII is the most important tool for writing exception safe code. 6 Conclusion The use of C++ for safety-critical systems is possible, provided that an appropriate coding standard such as MISRA-C++ or JSF C++ is followed, and appropriate tools that automatically check the conformance of all source code are used. A comparison of two C++ coding standards for safety-critical systems, MISRA-C++ and JSF C++, shows some interesting similarities, differences and also conflicts. Any programmer intending to write safety-critical code in C++ should familiarize himself with both coding standards, as they give a great insight into the potential hazards one has to deal with when using C++ in critical code. References [1] ISO/IEC 14882 International Standard: Programming Languages C++, Second Edition, ISO/IEC, 2003 [2] MISRA-C: 2004 Guidelines for the use of the C language in critical systems, MIRA Limited, 2004. [3] Joint Strike Fighter Air Vehicle C++ Coding Standards for the System Development and Demonstration Program, Lockheed Martin Corporation, 2005 [4] MISRA-C: 2008 Guidelines for the use of the C++ language in critical systems, MIRA Limited, 2008. [5] David Abrahams, Exception-Safety in Generic Components, http://www.boost.org/more/generic_exception_safety.html 2 This has mostly to do with missing support for exceptions in the compiler used in the JSF project. 3 http://en.wikipedia.org/wiki/resource_acquisition_is_initialization 4 Smart pointers have limited use in safety-critical code, as the use of dynamic memory is severely restricted.