Use of the C++ Programming Language in Safety Critical...

171
Use of the C++ Programming Language in Safety Critical Systems Flight Lieutenant Derek W. Reinhardt This report is submitted to satisfy the project requirements of the Masters of Science in Safety-Critical Systems Engineering at the Department of Computer Science September 2004 Number of words = 43,104, as indicated by the Microsoft Word ‘word count’ tool. The count includes the Title Page, Preliminaries, Report Body and References. Appendixes 1 to 16 contain design evidence that is included for completeness and has not been included in the word count.

Transcript of Use of the C++ Programming Language in Safety Critical...

Page 1: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

Use of the C++ Programming Language

in Safety Critical Systems

Flight Lieutenant Derek W. Reinhardt

This report is submitted to satisfy the project requirements of the

Masters of Science in Safety-Critical Systems Engineering

at the Department of Computer Science

September 2004

Number of words = 43,104, as indicated by the Microsoft Word ‘word count’ tool. The count

includes the Title Page, Preliminaries, Report Body and References. Appendixes 1 to 16 contain

design evidence that is included for completeness and has not been included in the word count.

Page 2: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

i

Abstract

The use of software for high integrity and safety critical applications is continuing to rapidly grow.

However, concerns are often raised because of the potentially disastrous consequences of a failure

of the software. C++ is a popular computer programming language, and thus there has been recent

interest in exploring its use for high integrity and safety critical applications. Likewise the object-

oriented paradigm is now widely used in the commercial and industrial sectors. C++ implements an

interpretation of this paradigm and there is now interest to move the paradigm into the safety critical

domain.

A number of reasons have been identified as to why the unrestricted use of the C++ language is not

suitable for high integrity and safety critical applications. However a subset of the language may

provide the restrictions necessary to make C++ suitable. The High Integrity C++ (HICPP) Coding

Standard [PRG03] has been identified as a suitable starting point for examining a safer C++ subset.

HICPP has been examined in the context of known C++ behaviours, best practice (problems and

solutions), and against a currently accepted definition of a safe programming language. It has also

been assessed in relation to the guidelines defined in the Handbook for Object-Oriented Technology

in Aviation [OOT04]. A number of additional rules and guidelines have been defined to address

identified deficiencies in HICPP and thus define a safer C++ subset.

A Goal Structuring Notation (GSN) pattern for justifying the selection of a programming language

for safety critical systems has been developed. The GSN pattern has been evaluated against the

safer C++ subset. Through this evaluation it has also been possible to demonstrate how a safety

critical project utilising C++ might instantiate such a safety argument. A method is also proposed to

evaluate its accuracy and applicability to other programming languages, and to real world projects.

This project has concluded that it is possible to use C++ to write software for use in high integrity

and safety critical applications. This may be achieved though the use of the safer C++ subset

(HICPP and additional rules) and a number of software tools for enforcement, static analysis and

dynamic testing. In conjunction, some degree of manual code reviews and design inspection are

also required. The project has also identified a few areas where improved tool support would better

facilitate safety critical software development in C++.

Page 3: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

ii

Acknowledgments

The completion of this project would not have been possible without the help of many people.

I would like to thank the Royal Australian Air Force for their support, sponsorship and for giving

me the chance to pursue this degree in England.

I would like to thank my project supervisor, Richard Hawkins, for his invaluable guidance and

advice throughout the project. This thanks is further extended to Tim Kelly for his role in

overseeing Richard as my project supervisor.

I would also like to thank Clive Pygott and his group at QinetiQ for providing a valuable conduit

for discussion.

I would like to thank The Programming Research Group, and in particular Tony Coomber, for

providing me documentation, discussion opportunities and advice on their High Integrity C++

(HICPP) Coding Standard Manual. In addition I would like to thank them for providing a full

working copy of the QA C++ Source Code Analyser for use throughout my project.

I would like to thank Gimpel Software, for providing a full working copy of PC-Lint and the

associated documentation for use throughout my project.

I would like to thank Advantage Technical Consulting, and in particular Andy Hodgkinson, for

providing me documentation and advice on MALPAS.

I would like to thank IPL Information Processing Ltd for providing allowing me access to a full

working copy of Cantata++ and the associated documentation for use throughout my project.

Finally I would like to thank my family and friends for their love and support always.

Page 4: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

iii

Table of Contents

Abstract.................................................................................................................................................i

Acknowledgments................................................................................................................................ii

Table of Contents ...............................................................................................................................iii

List of Tables ....................................................................................................................................... v

List of Figures .................................................................................................................................... vi

1 Introduction.................................................................................................................................1

1.1 Background......................................................................................................................................... 1

1.2 Safety Critical Systems and Software............................................................................................... 1

1.3 Project Aim, Background and Motivation....................................................................................... 2

1.4 Project Scope....................................................................................................................................... 3

1.5 Report Structure and Layout ............................................................................................................ 3

2 Literature Review ........................................................................................................................5

2.1 The C++ Programming Language .................................................................................................... 5

2.2 Programming Languages and Safety Critical Software ............................................................... 14

2.3 Programming Languages and Safety Standards ........................................................................... 22

2.4 Object-Oriented Technology in Safety Critical Systems .............................................................. 27

2.5 C in Safety Critical Systems ............................................................................................................ 28

2.6 C++ in Safety Critical Systems........................................................................................................ 30

2.7 Alternatives to C++ in Safety Critical Systems.............................................................................. 35

2.8 Software Safety Case Arguments.................................................................................................... 36

2.9 Verification and Validation of Safety Critical Software............................................................... 38

2.10 Summary of Literature Review .................................................................................................. 39

3 Analysis of the C++ Language .................................................................................................40

3.1 Identification of C++ Behaviour Ambiguities................................................................................ 40

3.2 Identification of C++ Best Practice, Problems and Solutions....................................................... 41

3.3 Identification of OOTiA Recommendations .................................................................................. 41

3.4 Summary and Direction................................................................................................................... 42

4 Development and Enforcement of a Safer C++ Subset ...........................................................43

4.1 Assessment of the High Integrity C++ Coding Standard.............................................................. 43

4.2 Development of Additional Rules.................................................................................................... 45

4.3 Rules and Guidelines Not Referenced in the Assessment ............................................................. 51

4.4 Enforcement of C++ Rules and Guidelines .................................................................................... 53

4.5 Summary of Definition of Safer C++ Subset.................................................................................. 57

5 Arguments for Programming Language Selection..................................................................58

5.1 GSN Argument for Programming Language Selection ................................................................ 58

5.2 Summary of GSN Argument for Programming Language Selection .......................................... 67

Page 5: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

iv

6 Evaluation of Safer C++ Subset and Safety Arguments .........................................................68

6.1 Evaluation of Safer C++ Subset Against GSN Argument ............................................................ 68

6.2 Evaluation of Safer C++ Subset Against Safe Language Criteria ............................................... 76

6.3 Proposal for Evaluating the GSN Argument ................................................................................. 82

7 Conclusions and Further Work................................................................................................85

7.1 Findings and Traceability to the Project’s Aims ........................................................................... 85

7.2 Further Work ................................................................................................................................... 87

References .........................................................................................................................................88

Appendix 1 – HICPP Coverage of Industrial Strength C++ Items................................................1-1

Appendix 2 – HICPP Coverage of Effective C++ Items.................................................................2-1

Appendix 3 – HICPP Coverage of More Effective C++ Items.......................................................3-1

Appendix 4 – HICPP Coverage of Effective STL Items.................................................................4-1

Appendix 5 – HICPP Coverage of C++ Gotchas ............................................................................5-1

Appendix 6 – HICPP Coverage of Exceptional C++ Items............................................................6-1

Appendix 7 – HICPP Coverage of OOTiA Guidelines ...................................................................7-1

Appendix 8 – Unspecified Behaviour (C++ Language) .................................................................8-1

Appendix 9 – Unspecified Behaviour (C++ STL) ...........................................................................9-1

Appendix 10 – Undefined Behaviour (C++ Language)................................................................10-1

Appendix 11 – Undefined Behaviour (C++ STL) .........................................................................11-1

Appendix 12 – Implementation-Defined Behaviour (C++ Lang) ................................................12-1

Appendix 13 – Implementation-Defined Behaviour (C++ STL)..................................................13-1

Appendix 14 – Indeterminate Behaviour (C++ Language)..........................................................14-1

Appendix 15 – Rule and Guideline Enforcement Required.........................................................15-1

Appendix 16 – Programming Language Selection Pattern..........................................................16-1

Page 6: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

v

List of Tables

Table 1: Ratings of Language Characteristics [Law97] .................................................................................................. 16

Table 2: Support Tools and Programming Language – Part 3, Table A.3 [IEC98] ........................................................ 24

Table 3: Detailed Design – Part 3, Table A.4 [IEC98] .................................................................................................... 24

Table 4: Design and Coding Standards – Part 3, Table B.1 [IEC98].............................................................................. 25

Table 5: C++ Language Unspecified Behaviour (partial extract from Appendix 8) ....................................................... 40

Table 6: Industrial Strength C++ Items (partial extract from Appendix 1) ..................................................................... 41

Table 7: OOTiA Guidelines (partial extract from Appendix 7) ........................................................................................ 42

Table 8: HICPP Coverage of Industrial Strength C++ Items (partial extract from Appendix 1) .................................... 43

Table 9: HICPP Coverage of Industrial Strength C++ Items (partial extract from Appendix 1) .................................... 56

Table 1-1: HICPP Coverage of Industrial Strength C++ Item .......................................................................... Appendix 1

Table 2-1: HICPP Coverage of Effective C++ Items......................................................................................... Appendix 2

Table 3-1: HICPP Coverage of More Effective C++ Items ............................................................................... Appendix 3

Table 4-1: HICPP Coverage of Effective STL Items .......................................................................................... Appendix 4

Table 5-1: HICPP Coverage of C++ Gotchas ................................................................................................... Appendix 5

Table 6-1: HICPP Coverage of Exceptional C++ Items.................................................................................... Appendix 6

Table 7-1: HICPP Coverage of OOTiA Guidelines............................................................................................ Appendix 7

Table 8-1: C++ Language Unspecified Behaviour [BSI03] .............................................................................. Appendix 8

Table 9-1: C++ STL Unspecified Behaviour [BSI03]........................................................................................ Appendix 9

Table 10-1: C++ Language Undefined Behaviour [BSI03]............................................................................. Appendix 10

Table 11-1: C++ STL Undefined Behaviour [BSI03] ...................................................................................... Appendix 11

Table 12-1: C++ Language Implementation-Defined Behaviour [BSI03] ...................................................... Appendix 12

Table 13-1: C++ STL Implementation-Defined Behaviour [BSI03] ................................................................ Appendix 13

Table 14-1: C++ Language Indeterminate Behaviour [BSI03] ....................................................................... Appendix 14

Table 16-1: Programming Language Selection Pattern................................................................................... Appendix 16

Page 7: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

vi

List of Figures

Figure 1: Evolution of Programming Languages [Ver03] ................................................................................................. 7

Figure 2: Single Inheritance............................................................................................................................................... 9

Figure 3: Multiple Inheritance ........................................................................................................................................... 9

Figure 4: Complications of Multiple Inheritance ............................................................................................................. 10

Figure 5: Defined Safer C++ Subset [PRG03] ................................................................................................................ 34

Figure 6: Better representation of a Safer C++ Subset ................................................................................................... 35

Figure 7: Goal .................................................................................................................................................................. 36

Figure 8: Evidence ........................................................................................................................................................... 36

Figure 9: Strategies .......................................................................................................................................................... 36

Figure 10: Assumptions / Justifications............................................................................................................................ 36

Figure 11: Context............................................................................................................................................................ 36

Figure 12: Solved By / In Context Of................................................................................................................................ 36

Figure 13: GSN Process Overview [HRM04] .................................................................................................................. 37

Figure 14: Key to GSN Extensions [HRM04] .................................................................................................................. 37

Figure 15: Top Level Argument (partial extract from Figure 16-1)................................................................................. 60

Figure 16: Correct Implementation Argument (partial extract from Figure 16-1) .......................................................... 60

Figure 17: Error Prevention Argument (partial extract from Figure 16-2)..................................................................... 61

Figure 18: Run-time Error Argument (partial extract from Figure 16-4)........................................................................ 61

Figure 19: Definition Argument (extract from Figure 16-5) ............................................................................................ 62

Figure 20: Common Error Sources Argument (extract from Figure 16-7) ...................................................................... 64

Figure 21: Error Detection Argument (extract from Figure 16-3)................................................................................... 65

Figure 22: Static Analysis Argument (extract from Figure 16-10)................................................................................... 66

Figure 23: Dynamic Testing Argument (extract from Figure 16-11) ............................................................................... 67

Figure 16-1: Top-Level Argument.................................................................................................................Appendix 16-1

Figure 16-2: Error Prevention Argument......................................................................................................Appendix 16-2

Figure 16-3: Error Detection Argument........................................................................................................Appendix 16-2

Figure 16-4: Run-Time Error Argument .......................................................................................................Appendix 16-3

Figure 16-5: Definition Argument.................................................................................................................Appendix 16-3

Figure 16-6: Behaviours Subset Argument....................................................................................................Appendix 16-4

Figure 16-7: Common Error Sources Argument ...........................................................................................Appendix 16-4

Figure 16-8: Other Error Sources Argument ................................................................................................Appendix 16-5

Figure 16-9: Strongly Typed Argument.........................................................................................................Appendix 16-5

Figure 16-10: Static Analysis Argument........................................................................................................Appendix 16-6

Figure 16-11: Dynamic Testing Argument ....................................................................................................Appendix 16-6

Page 8: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1

1 Introduction

1.1 Background

The use of software for high integrity and safety critical applications is rapidly growing. While

many of these applications still exist purely within the defence or space industries, there are also

many applications that interact with the general population. The anti-lock braking system (ABS) in

the modern car, the control and signalling systems used on the railway networks, and the fly-by-

wire systems in modern commercial aircraft are a couple of examples of such systems. In fact, on a

daily basis it is difficult for many people to avoid coming into contact with systems that are

controlled by software. Such a scenario presents a number of issues.

Firstly, concerns are often raised because of the potentially disastrous consequences of a failure of

software resident within safety critical applications. Thus it is crucial that the underlying design

principles for safety critical systems are not compromised and that the systems can be shown to be

acceptably safe.

Secondly, with this growth, the number of people involved with the development of these systems

has increased proportionally. This has resulted in an influx of mainstream software technologies

into the safety critical domain. Furthermore, it is arguable that traditional high integrity languages

are becoming obsolete, and that there is interest within industry to move to more commercial

development environments [Wic98]. Some developers are complaining that it is not practical to

perform safety critical development in languages they can not recruit sufficient competent

programmers for [Wic98]. C++ is a popular computer programming language, which is touted to be

both widely used and understood. Most computing graduates from universities will have had at least

some exposure to the language regardless of the chosen teaching language at the particular

institution from which they graduated. There is also a plethora of tools and development

environments available to support the language. Thus there has been recent interest in exploring its

use for high integrity and safety critical applications.

1.2 Safety Critical Systems and Software

To assist with defining the aim of this project, it is first worthwhile establishing a good definition

for safety critical systems, high integrity systems, and safety critical software. For the purposes of

this report the terms safety critical systems and high integrity systems shall be used synonymously.

This is because of the seemingly interchangeable use of both terms throughout the literature

examined in Section 2.

[Bar02] defines high integrity systems as “systems for which failure can cause loss of life, injury,

environmental damage, or financial loss … the cost of failure is not tolerable or affordable.” This

definition focuses on the outcomes of failure. [IPL96] offers a slightly reworded definition of a

safety critical system as “a system where human safety is dependent on the correct operation of the

system.”

In a similar theme and considering software specifically, [MoD97] states that safety critical

software is “software that relates to the safety critical function or system, ie. software of the highest

safety integrity level (S4), the failure of which could cause the highest risk to human life.” [IPL96]

points out though that safety must always be considered with respect to the whole system (ie. safety

is a system issue [Dou98]). Thus in addition to the software, the computer hardware, other

electronic and electrical hardware, mechanical hardware, developers, operators and users must also

be considered [IPL96].

Page 9: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

2

While on the topic of definitions, it is also worth considering the terms safety and reliability.

[Dou98] points out that safety is not reliability! A reliable system does not fail very often, but if it

does fail it makes no guarantees about what will happen. On the other hand, a safe system can fail

frequently, even though this is probably undesirable, but provided that it fails in a safe way, the

system is still safe.

When developing systems that have a potential to impact upon safety, software or otherwise,

[IPL96] describes a number of questions that should be addressed through the development of the

system. The answers to these questions should be documented as part of the safety case for the

system. These are as follows.

• Can it present hazards to safety?

• What can be done to reduce the hazards to an acceptable level?

• How can it be verified that the developed system is safe?

It is also important to consider the approaches and philosophies commonly adopted for the

development of safety critical systems. [IPL96] describes two distinct philosophies for the

specification and design of safety critical systems:

• “To specify and design a ‘perfect’ system, which cannot go wrong because there are no faults

in it, and to prove that there are no faults in it.” Such a philosophy lends itself to the formal

mathematical proof of design correctness being established. For large, complex systems, this

may be difficult.

• “To aim for the first philosophy, but to accept that mistakes may have been made, and to

include error detection and recovery capabilities to prevent errors from actually causing a

hazard to safety.” This means that within the software it is able to check that inputs are valid

(pre-conditions), to trap errors within the routine (assertions and proofs), and to ensure the

outputs are safe (post-conditions). At a higher level, one part of the system can independently

check that the rest of the system is behaving correctly, and vice versa.

These questions and design philosophies shall be reflected upon throughout the project.

1.3 Project Aim, Background and Motivation

The aim of this project is examine the use of the C++ programming language in the context of

safety critical systems. There is a significant amount of opinion that says that safety critical systems

in C++ are not feasible [Wic98]. But what are really the concerns? There may be inherent conflicts

of interest in some of these opinions as often the same organisations offering opinions also market

tools for their advocated language. Thus they would be at some financial advantage to have the

language that their tools support to be deemed suitable for safety critical systems.

This project endeavours to examine justifiable evidence relating to the use of C++ in safety critical

systems. This project has specifically sought answers to the following questions.

• Can the C++ programming language be used for the development of safety critical systems?

• If the C++ programming language as a whole is not suitable for safety critical systems, then

can constraints and restrictions be placed on the language (ie. language sub-setting) to permit

its use? What would these constraints and restrictions be? Can they be appropriately defined?

Are they sufficient?

Page 10: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

3

• What tools are currently available to support the development of safety critical software using

the C++ programming language? Do the tools support verification of the software’s safety?

• What do the applicable safety standards say and could C++ be justified within the context of

these standards? How could justification be achieved?

1.4 Project Scope

This project is centred towards answering the questions defined in Section 1.3 and hence

determining if C++ can be used for safety critical system development. A number of these questions

are significant in scope. In order to facilitate the completion of the project in the allocated

timeframe, several limitations have had to be placed on the scope of the project.

Two distinct approaches have been employed in examining C++ for safety critical systems. The

first has been to examine C++ behaviours, best practice (problems and solutions) and paradigm

related issues. These have been examined in the context of C++ as a whole language, with due

consideration to subsetting as required. Although several subsets were identified, this project has

restricted its specific examination of a C++ subset to the High Integrity C++ (HICPP) Coding

Standard as defined in [PRG03]. It is not possible to consider more subsets in detail due to the scale

of analysis required for each subset. HICPP was identified early within the project lifecycle as

having many of the qualities required of a safer C++ subset and thus it shall form a central part in

this project.

The second approach has been to develop a justification argument for the selection of programming

language based on the material reviewed in the literature review. This material includes academic

papers, commercial literature and standards. The project has limited the examination of safety

standards to IEC61508, RTCA/DO178B, Defence Standard 00-55 Issue 2 and Defence Standard

00-56 Issue 3.

The evaluation phase of the project works to bring together the two approaches and evaluate the

adequacy of the approaches in relation to each other. Both approaches and the evaluation shall form

the basis on which the conclusions are to be stated.

This project has examined the role that the tools QA C++, PC-Lint / FlexeLint, Cantata++ and

MALPAS can play in high integrity C++ software development. It is not possible to consider every

other tool that might be available. However the project shall examine a mechanism for arguing the

role that potentially any C++ tool can play in the development of high integrity C++ software.

1.5 Report Structure and Layout

This report presents the research, analysis, investigation, evaluation, conclusions and

recommendations of the project and is structured as follows.

Section 2 presents a review of literature deemed relevant to the context of the project. The review

examined the C++ programming language, programming languages in relation to safety critical

software and relevant standards, object oriented technology in safety critical software, and

applications to date involving C++ in the safety critical domain.

Section 3 presents an examination of properties of the C++ programming language and examines

why a subset might improve the safety associated with the use of C++. Unspecified, undefined,

implementation-defined and indeterminate behaviours of C++ are identified. In addition best

practice, problems and solutions, in C++ are also identified. Finally guidance in relation to the use

of the object-oriented paradigm is also identified.

Page 11: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

4

Section 4 presents an assessment and identifies deficiencies of the HICPP coding standard against

the properties identified in Section 3. From this a safer C++ subset is defined. The automatic

enforcement of these rules and guidelines is also examined.

Section 5 presents the development of a justification argument pattern for the selection of a

programming language for a safety critical system.

Section 6 presents an evaluation of the safer C++ subset against the justification of programming

selection pattern. It also details an evaluation of the safer C++ subset against identified criteria for a

safe programming language. Further evaluations are proposed for evaluating the argument pattern

against existing safety cases and design documentation, as well as evaluating the safer C++ subset

within the context of safety critical projects.

Section 7 presents the conclusions and recommendations from the project. It also details proposals

for future work considered necessary as a result of observations made during the project.

Appendix 1 - 6 presents the results of the C++ best practice, problems and solutions assessment.

Appendix 7 presents the results of the OOTiA guidelines assessment.

Appendix 8 - 14 presents the results of the unspecified, undefined, implementation-defined and

indeterminate behaviours C++ assessment.

Appendix 15 presents a list of the rule and guideline enforcement required.

Appendix 16 presents a safety case pattern for arguing the selection of a particular programming

language for a safety critical system.

Page 12: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

5

2 Literature Review

2.1 The C++ Programming Language

The C++ programming language is one of the most popular programming languages available to

programmers today. It is generally known throughout programming circles as an expressive multi-

paradigm programming language that is powerful for solving demanding problems. In its ANSI/ISO

standardised form it is also portable across different hardware architectures. Unfortunately though,

if C++ is used without discipline it can lead to code that is “incomprehensible, unmaintainable,

inextensible, inefficient, and just plain wrong” [Mey98]. In fact some might claim that it is too

complex for all but a few to master. For these reasons and more, advocates of languages such as

Ada and Java rarely have positive comments to associate with C++.

C++ has features that make it suitable for writing the smallest of command line utilities (eg. < 1,000

lines of code), right up to very large-scale complex software systems (eg. > 1,000,000 lines of

code). The language also implements an interpretation of the object-oriented paradigm that has

helped programmers to increase software productivity, quality and re-useability [Dei94].

C++, along with Ada and Java, are third generation programming languages according to [Law97].

[Sch03] describes C++, along with C and Java as middle level languages. The lowest level,

practically useable language is assembly language. Languages such as Ada, Modula-2, and Pascal

are high-level languages. Because it is a middle level language C++ should not be considered less

powerful than the high level languages. It is middle level because it combines the best aspects of

high-level languages, while still allowing the programmer the control and flexibility of assembly

language [Sch03]. This strengthens its suitability for system-level programming such as the

development of operating systems, interpreters, compilers, and device drivers.

C++ is a structured language, as is Ada, Pascal, Java, C and Modula-2. A structured language

allows for the separation, and encapsulation of code and data. This allows programmers using one

module to only require knowledge of an interface. The programmer does not need to know how the

interface is specifically implemented. In fact the implementation may be changed, and so long as

there are no changes to the interface, then the modules accessing the functionality described by the

interface need not change. There are a few specific characteristics of C++ interfaces that may be

exceptions to this case but generally the principle is the same. [Sch03] also points out that C++ is

not strictly a block-structured language. This is because it does not permit the declaration of

procedures or functions within other procedures or functions.

This section examines the ancestry of the C++ programming language to gain an appreciation of the

influences that have worked to mould the C++ of today. Such an appreciation is important when

later considering C++ in the context of safety critical software. The section also briefly examines

the ANSI/ISO standardisation that, while many years in the coming, has been welcomed across the

C++ community.

2.1.1 Ancestry of the C++ Programming Language

In the world before C++, primal computer chaos reigned! Well, maybe there is no need to be quite

so melodramatic, but its development has certainly been born out of a rapid expansion in diversity

of computer-programming languages. As time passed, languages combined, evolved and matured.

Some languages prospered, while others vanished. This section now examines the ancestry that is

responsible for producing the C++ language as it is today.

Prior to the 1940s, computers were programmed by being ‘hard-wired’. This meant that links or

switches were set by the programmer to instruct the computer as to what operation to perform

Page 13: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

6

[Lou93]. While at the time this was suitable enough for the complexity of computers available, it

was soon to become an outdated and inefficient technique.

In the 1940s John von Neumann came up with the idea that rather than ‘hard-wiring’ a computer’s

operation, it should instead use a series of codes or instructions stored as data to determine the

operations performed [Lou93]. Thus we saw the birth, at least in concept, of machine code - the

language of the machines. Unfortunately, the language of the machines did not equate easily to the

languages of people. Hence there was a need for further evolution of this concept. In fact such an

idea can be closely related to [Lou93]’s definition that a programming language is “a notional

system for describing computation in machine-readable and human-readable form.”

The first creditable advance in a human readable form of a computer programming language was

assembly language. Assembly language provided a means of providing names for instructions, data

and locations. This meant the programmers no longer had to face the insanity of long strings of

hexadecimal digits (0..9 and A..F, eg. FE26) or worse still binary digits (0 or 1, eg.

00101110110101011). However, assembly language is very machine dependant and has only a low

level of abstraction [Lou93]. Hence the reference to it being a low-level language. It can also be

difficult to both write and then subsequently understand [Lou93].

In an effort to reduce the level of machine dependency and increase a programmer’s ability to write

concise, understandable instructions the notion of a higher level of abstraction (high-level language)

was realised [Lou93]. In 1945, the German K. Zuse, inventor of the Z3 computer, also worked on

defining an evolved language for the Z3 [Sur04]. However little evidence and few documents still

exist. The late 1950s saw the birth of the first truly high-level programming languages including

Fortran, Cobol and Lisp. In fact most modern programming languages can trace at least some aspect

of their language definition to these early languages. Figure 1 shows a graphical representation of

the evolution of most modern programming languages and how their origins can be traced back to

these first high level languages.

According to [Ver03], Fortran is the earliest high level language from which C++ has evolved.

Fortran, which stands for FORmula TRANslation system, was first developed in 1954 and is a

language dedicated to scientific-numeric purposes [Ver03]. It was developed by John Backus and

other researchers at IBM [Sur04]. Fortran continued to evolve with numerous versions being

released (Fortran I, II, III, IV, 66, 77, 90 and 95). It is still used today for programming scientific

and mathematical applications.

Algol (ALGOrithmical Language) (1958) was designed to be the successor of Fortran by an

international consortium of computer scientist specialists. Although ALGOL didn’t succeed in

replacing Fortran, in fact [Sur04] suggests that no compiler can be found, this language is credited

as having a major impact on the evolution of programming languages [Ver03].

In the early 1960s the Combined Programming Language (CPL) was developed by Cambridge and

London Universities [Ver03]. Developed using some functional language properties in combination

with the Algol60 definition, the language was developed to supposedly cope with all possible kinds

of problems [Ver03], perhaps a little like Ada was in more recent times. However, much of the

language was never implemented.

During a visit to the Massachusetts Institute of Technology in 1967, Martin Richards (Cambridge

University) created a simplified version of CPL called Basic CPL (BCPL) [Ver03]. This language

was used up until the late 1980s at numerous establishments including Cambridge and Oxford

Universities [Ver03].

Page 14: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7

Figure 1: Evolution of Programming Languages [Ver03]

In 1969 Ken Thompson at Bell Labs decided Unix needed a system programming language. Ken

Thompson created B, a trimmed down version of BCPL (which in itself was a simplified version of

CPL) to fit into the 8Kb of RAM on the DEC PDP-7. No other programs, except B itself, were ever

written in the language for this machine [Ver03]. When Bell Labs acquired a new DEC PDP-11

with 24Kb RAM, the B language was ported to this new machine. Many programs were written in

B for this machine, however it also exposed a number of inadequacies of B’s semantic model

[Ver03].

In 1971, the B language was expanded by Dennis Ritchie and the name was changed to C (after a

intermediate stint as New B, or NB) [Ver03]. In the years to follow the language was further

expanded, several times. Not only was the Unix kernel completely re-written in C, but the language

was also ported to numerous other platforms [Ver03]. The popularity among programmers grew and

the language was to be ANSI standardised from 1983 to 1989, and again in 1999. It has been one of

the most popular programming languages of all times and has been used to develop software from

operating systems to word-processors, games to computer animations in movies, and about

everything in between.

Page 15: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

8

Throughout the time that CPL and BCPL were being developed, the Simula (SIMULAtion)

language was also being developed [Ver03]. Built on a number of features of Algol, it was

principally designed for simulation and modelling purposes, but was also later extended as a

general-purpose language [Ver03]. Although it was never really successful [Ver03], it was the first

object-oriented language and introduced classes, inheritance and objects [Sur04].

Before moving onto describing object-oriented programming in further detail, and then

subsequently covering the development of C++ from C and Simula, it is worth highlighting a few

points about Figure 1.

It can be seen that there have been many other programming languages developed than those that

directly led to the development of C or C++. So why are there so many programming languages?

[Pri03] describes that every language is a trade-off among a number of competing pressures.

Importantly [Pri03] also states that “notation is important.” Thus, the closer the language to the

problem domain, the easier it is for programmers to be able to produce elegant and comprehendible

solutions [Pri03]. This will be important when the problem domain of safety critical systems is

considered.

While Figure 1 does indeed highlight the birth date for the languages it covers, and the previous

influences on a language’s development, it is important to note that the diagram does not clearly

indicate the lifetime of the languages. Many of the languages are still in use today, and some of the

languages have even evolved within themselves over that time.

2.1.2 Object-Oriented Programming

Before discussing the object-oriented aspects of the C++ language it is first worthwhile to briefly

discuss some general principles of the object-oriented paradigm. Object-oriented programming

addresses two significant issues in software design: the need to reuse software components, and the

need to maintain independence of these different components [Lou93]. [Lou93] lists five basic ways

that a software component can be modified for reuse: extension, restriction, redefinition,

abstraction, and polymorphism. These are the key attributes of an object-oriented programming

language. However, the goal of object-oriented programming is not only to allow the reuse of

software components. It also allows restrictions, or protection mechanisms, to be placed on access

to the internal details of a software component.

2.1.2.1 Objects, Classes, Instance Variables and Methods

There are a number of basic components of an object-oriented programming language: objects,

classes, instance variables and methods. An object is “something that occupies memory and has

(modifiable) state” [Lou93]. According to [OOT04] it contains both code (functions) and data

(structures). The state of an object is internal or local to the object itself and is represented by

instance variables, which are local variables declared as part of the object [Lou93]. An object can be

declared by creating an instantiation of the local state and methods, which is otherwise known as a

class. A class is similar to a data type, but it also includes a definition of the functionality that may

be enacted on its data type. [OOT04] defines a class as “a set of objects that share the same

attributes, methods, relationships, and semantics – they share a common structure and behaviour.”

Each object (instantiated from a given class) contains a set of functions and procedures through

which the local state can be assessed and changed [Lou93]. These functions and procedures are

known as methods.

2.1.2.2 Abstraction, Encapsulation & Modularity

“Abstraction denotes the essential characteristics of an object that distinguishes it from all other

objects and thus provides crisply defined conceptual boundaries” [OOT04]. The object is the device

Page 16: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

9

that supports encapsulation, as it is the mechanism that binds code (functionality and behaviour)

and the data (attributes) it manipulates together [Sch03]. The encapsulation also prevents outside

interference and misuse of the code and data within an object [Sch03]. Modularity entails the

partitioning of a program into logically separated and defined components. Abstraction,

encapsulation and modularity work together to support the object-oriented paradigm.

2.1.2.3 Typing and Polymorphism

[OOT04] cites a definition of typing as the “enforcement of the class of an object, such that objects

of different types may not be interchanged, or at most they may be interchanged only in very

restrictive ways.” Another concept that is closely related to typing is polymorphism. Polymorphism

allows one interface to control access to a general class of actions [Sch03]. Thus for the calling

function, the interface is less complex. It allows the programmer to write programs in a general

fashion to process a wide variety of existing and importantly yet to be specified related classes. The

specific action is determined by the class or type of the data being used. In some cases, the

polymorphism may occur at compile-time, but for others the polymorphism may be required to

occur at run-time.

2.1.2.4 Inheritance and Class Hierarchy

Inheritance is “the process by which one object can acquire the properties of another object”

[Sch03]. [Dei94] provides the following definition: “inheritance is a form of software re-useability

in which new classes are created from existing classes by absorbing their attributes and behaviours

and embellishing these with new capabilities the new classes require.” Through inheritance it

becomes possible to construct a class hierarchy of abstractions. For example a class B can inherit

some or all of the instance variables and methods of another class A (Figure 2). Class B is called the

sub-class or derived class of A, and class A is the base class, parent class or super class of B.

Inheritance is traditionally expressed as the is-a relationship.

class A

class B (inherits A)

Figure 2: Single Inheritance

In the case examined above, we have what is called single inheritance, since the sub-class only

inherits from one parent class. Some languages permit multiple inheritance. Thus is it possible that

a class may inherit from two or more parent classes (Figure 3).

class A class B

class C (inherits A,B)

Figure 3: Multiple Inheritance

Multiple inheritance is a powerful technique, but it can also be the source of numerous

complications. In particular it is possible that methods may be inherited in more than one way. For

example, in Figure 4 a method from class A is inherited by class D in two different ways. This

makes it difficult to resolve references to methods. What if for example, class B redefines a method

of A?

Page 17: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10

class A

class B (inherits A) class C (inherits A)

class D (inherits B,C)

Figure 4: Complications of Multiple Inheritance

Some languages such as Smalltalk and Java are restricted to single inheritance to avoid such

complications. C++ does permit multiple inheritance, and thus these problems will need to be

considered.

2.1.2.5 Dynamic Binding

If a method in a base class is defined as virtual, then that method is always available for objects of

the class, but the implementation is specific for each different derived class. Virtual methods are

sometimes also called deferred [Lou93]. The appropriate method is then invoked for each object

depending dynamically on which derived class the object belongs to. This is dynamic binding and

[Lou93] states that “dynamic binding is one of the main sources of power on an object-oriented

language.” Languages that strictly adhere to the object-oriented paradigm offer only dynamic

binding [Lou93]. However, most object-oriented languages tend to offer both static and dynamic

binding of methods [Lou93]. For example, if a method is declared as non-virtual then static binding

applies, whereas dynamic binding applies to virtual methods.

2.1.3 Development of the C++ Programming Language

C++ began as an enhanced or expanded version of C and was first invented by Bjarne Stoustrup in

1979 at Bell Laboratories, New Jearsey [Str00]. Bjarne’s motivation was that he wanted to add the

object-oriented facilities from Simula into the C language [Ver03]. In fact C++ was originally titled

‘C with classes’ [Dei94]. In conjunction with introducing these features, C++ also remains a

superset of C [Dei94]. Thus programmers can still use a C++ compiler to compiler C programs.

Although C++ contains the C language, [Sch03] points out that not all the features provided by C

are used when writing good C++ programs. For example the C++ I/O system is substantially

different to the C I/O system, though both are available to the programmer. The preprocessor is

another example.

[Dew3] points out that the terminology used when discussing C++ is slightly different to the object-

oriented paradigm described in Section 2.1.2. In C++ there are data members, member functions

and abstract classes, instead of instance variables, methods and (pure) virtual base classes. The C++

terminology shall be used in this report whenever specific C++ issues are being addressed.

C++ has undergone a number of major revisions since it was conceived [Str00]. The first revision

was in 1985 and the second was in 1990. The third and most recent revision occurred as part of the

standardisation of the language. A joint ANSI (American National Standards Institute) and ISO

(International Standards Organisation) standardisation committee was formed and in 1994 released

the first draft of the proposed standard. After what was a longer period than what many expected,

caused partially by the introduction of the Standard Template Library (STL) into the language, the

C++ (ANSI/ISO) standard was officially released in 1998 and is known as Standard C++. [BSI03]

defines Standard C++ and incorporates technical corrigendum No. 1.

Page 18: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

11

Some recent programming languages have descended from C++. These include Java, which largely

borrows the syntax of C++, but also places some refinement on pointers and memory management.

C# also draws its origins from C++ and is the main language of the .NET environment.

2.1.4 Reasons For Programming In C++

Section 2.1 mentions that the C++ programming language has become immensely popular. A

number of reasons for its popularity, summarised from advocates of the language, are as follows.

• [Sch03] describes C++ as the “universal language of programming.” [Sch03] supports this by

suggesting that it is common for algorithms or techniques to be first described using the C++

syntax. Many academic institutions also teach courses entirely within C++. In fact [Sch03]

also prophesises that C++ “will remain the pre-eminent language for the development of high-

performance software well into the foreseeable future.”

• C++ gives good support for high speed, low-level, input/output operations, which are

essential to many embedded applications. C++ is designed to generate smaller and less RAM-

intensive code than may other high-level languages. It also allows a programmer access to

some features that allow low-level control.

• C++ also remains a superset of C [Dei94]. Thus programmers can still use a C++ compiler to

compile C programs. C++ was originally designed with the intention that many C

programmers would in time migrate to using the language. In fact [Dei94] prophesied that by

the mid-1990s most major C programming environments would have converted to C++. It is

debatable as to whether this has actually occurred. C++ contains stronger type checking than

C. In fact the container classes provided in the Standard Template Library (STL) means that

programmers can move to safer alternatives for implementing types such as Strings, Arrays,

Lists and Queues. No longer is the programmer required to develop their own or rely on

existing (manual) pointer based implementations.

• C++ allows for the expression of abstract ideas through its implementation of the object-

oriented paradigm. C++ supports both single and multiple inheritance, though multiple

inheritance should not be used without appropriate considerations. C+ supports good software

engineering practices that that makes it more appropriate than those languages that don’t. C++

helps to promote software re-use. C++ can also be easily linked with modules programmed in

other languages such as C and assembler.

• The popularity of C++ has resulted in the wide availability of tools to support C++

development. Tools include compilers, development environments, static analysis tools,

coding style and rule checkers, dynamic test harness generators, and test point generators, to

name a few. Also a number of modelling packages are capable of auto-generating C++ code.

• C++ has been ANSI/ISO standardised.

Reiterating from Section 1.1, many of these reasons contribute to this project’s motivation for

determining if C++ can be used for the development of safety critical systems.

2.1.5 Best Practice, Problems and Solutions in C++

[Mey98] states that while “learning the fundamentals of a programming language is one thing,

learning how to design and program ‘effective’ programs is something else entirely.” [Mey98] goes

on to point out that this is especially true of C++ due to its “uncommon range of power and

expressiveness.” [Dew03] states that effective programming in C++ involves intelligent

Page 19: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12

coordination of many disparate areas. So how does a programmer master learning to design and

program ‘effective’ C++ while coming to grips with these many disparate areas? Because the C++

language is immensely popular, the volume of literature available on the language and its

application is immense. A significant subset of this literature specifically addresses the issues of

problems and solutions in C++ design and programming. In fact C++ in almost unique in the

number of textbooks available on such topics. Non C++ advocates might argue that this is because

of the principle number of flaws in the language.

The following sections review a number of significant C++ texts whose importance will be revealed

in Section 2.6.4. While a number of these texts present similar or overlapping material each has a

significant proportion of unique material so as justify its worth. The texts considered have been

highlighted because their discussion goes further than the many C++ reference texts available (eg.

[Str00] and [Sch03]). While these texts (referring to [Str00] and [Sch03]) are comprehensive guides

to the language, they tend not to provide specifics of problems and mis-interpretations of language

features.

The following sections are intended to highlight the coverage and knowledge available in published

literature on C++. Together these texts represent a very comprehensive and respected collection of

C++ programming knowledge. However, it would be unreasonably to assume their coverage is

complete. While they all point out more than a handful of areas where an un-supervised

programmer may get caught out, importantly they also highlight numerous solutions to dealing with

such problems.

2.1.5.1 Industrial Strength C++ [Hen97]

[Hen97] defines a C++ coding standard that they suggest is valid and useable for most C++

programmers. The text is intended to act as a good starting point for any organisation wishing to

produce a programming standard. Its origins can be traced back to an original a programming

standard written for a project in 1990 at Ellemtel Telecommunications Systems Laboratories in

Sweden [Hen97]. Interest in the programming standard by Bjarne Stroustrup, the initial inventor of

C++, resulted in it being freely available in 1992. Since the document was written C++ has changed

numerous times. [Hen97] represents the published form of a significant revision of the original

programming standard document that takes into account much of the ANSI/ISO standardisation.

The advice given by [Hen97] is divided into rules and recommendations. These are grouped under

the following list of categories:

• Naming

• Organising the Code

• Comments

• Control Flow

• Object Life Cycle

• Conversions

• The Class Interface

• New and Delete

• Static Objects

• Object-Oriented Programming

• Assertions

• Error Handling

• Parts of C++ to Avoid

• Size of Executables

• Portability

• Style

Page 20: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

13

2.1.5.2 Effective C++ [Mey98], More Effective C++ [Mey96], Effective STL [Mey01]

[Mey98], [Mey96], and [Mey01] are a series of C++ books by Scott Meyers that are aimed at

teaching the C++ programmer how to improve their programs and designs. These texts are widely

referenced by literature within the C++ community. Both experienced and inexperienced

programmers alike are likely to be awakened to many situations to which they were previously (and

probably blissfully) unaware. In recent times their intent and structure has been mirrored in

producing an ‘Effective’ Java textbook.

[Mey98] contains 50 specific suggestions on how to improve C++ programs and designs. It is a

revised edition of a text of the same titled published a number of years prior. [Mey98] offers advice

on general design strategies, as well as the specifics of particular language features. [Mey98] covers

issues relating to:

• Shifting from C to C++

• Constructors, Destructors and Assignment

Operators

• Inheritance and Object Oriented Design

• Memory Management

• Classes and Functions: Design,

Declaration and Implementation

• Other Miscellany of the Language

Interestingly [Mey98] states that although his initial interest was in programming rules that could be

automatically enforced, there were limitations to such an approach. Thus instead [Mey98] was

produced. This was due to the difficulty in formalising the guidelines and the number of significant

exceptions. These limitations may be important when enforcement of rules is later addressed.

[Mey96] contains 35 additional (to [Mey98]) specific suggestions on how to improve C++

programs and designs. The text is focused more on the most recent language features to be added to

the C++ standard, as well as the more advanced programming techniques [Mey96]. [Mey96] covers

issues relating to:

• Basics

• Operators

• Exceptions

• Efficiency

• Techniques

• Other Miscellany of the Language

[Mey01] contains 50 specific ways to improve the use of the Standard Template Library (STL). The

STL provides general-purpose, template classes and functions that implement commonly used

algorithms and data structures [Sch03]. The STL is constructed from template classes to allow them

to be applied to nearly any type of data [Sch03]. However, the STL is a complex piece of software

engineering, and a programmer must have a complete understanding of the C++ language to fully

harness the STL. Most C++ programming books provide an introduction and a guide to using the

STL. [Mey01] differs in that it assumes the reader knows about the STL. Instead the focus is on

how to avoid the pitfalls and use the STL ‘effectively’. [Mey01] covers issues relating to:

• Containers

• Vector and String

• Associative Containers

• Iterators

• Algorithms

• Functors, Function Classes, & Functions.

• Programming with the STL

Page 21: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

14

2.1.5.3 Exceptional C++ [Sut00]

[Sut00] shows by example how a programmer should go about sound software engineering in C++.

Firstly a C++ problem or puzzle is presented to the reader to ponder over. This is then followed by a

description and explanation of the one or more possible solutions to the problem. In doing so a

number of programming guidelines are highlighted to the reader. Some of the material published in

this text has been derived from the ‘Guru of the Week’ on the internet newsgroup

comp.lang.c++.moderated.

[Sut00] presents 47 puzzles, programming problems and solutions and covers issues relating to:

• Generic Programming and the C++

Standard Library

• Exception Safety Issues and Techniques

• Class Design and Inheritance

• Compiler Firewalls and the Pimpl Idiom

• Name Lookup, Namespaces, and the

Interface Principle

• Memory Management

• Traps, Pitfalls and Anti-idioms

• Other Miscellaneous Topics

2.1.5.4 C++ Gotchas [Dew03]

[Dew03] details 99 gotchas of the C++ programming language. [Dew03] defines C++ gotchas as

“common and preventable problems in C++ programming and design.” As well as presenting the

gotchas, [Dew03] also highlights that the “careful, accurate use of patterns and patterns terminology

in design and documentation clarifies code and helps prevent gotchas from occurring”. [Dew03]

describes some of these patterns. [Dew03] covers gotchas relating to:

• C++ Basics and Syntax

• The Preprocessor

• Conversions

• Initialisation

• Memory and Resource Management

• Polymorphism

• Class Design

• Hierarchy Design

[Dew03] describes that there are numerous nuances of the C++ language. It is these nuances that are

often misunderstood by programmers and thus can frequently lead to the gotchas described by

[Dew03]. However, [Dew03] also suggests that the inclusion of these nuances in the language is

deliberate, as expert programmers engaging in advanced programming and design often find uses

for them.

2.2 Programming Languages and Safety Critical Software

Despite a lack of certainty as to whether an accident has ever been contributed to the choice of

programming language [Wic98], the programming language is central to the role of translating the

intended design into actual computer code to run on the target system. Even with a safe design, it is

possible to affect the system’s safety depending on how the software is written [Dou98]. If the

system safety analysis has resulted in a set of derived safety requirements, and these requirements

must be met by the implementation, or the error detected and the system failed to a safe state, then

the programming language plays a critical role in correctly implementing such requirements. If

design flaws are introduced because of the language choice then this is clearly unacceptable. In

addition it would also be beneficial that where possible the language itself might be able to detect

flawed designs.

Page 22: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

15

This section considers the characteristics of programming languages from numerous perspectives

and then sets about defining practical criteria against which a language can be assessed to determine

as to if it is likely to facilitate the correct implementation of the design and be deemed ‘safe’.

2.2.1 Good Programming Languages

Before considering what makes one programming language safer than another it is firstly worth

considering what makes a programming language a good programming language. After all, it is not

uncommon for one programmer during a debate with another programmer to raise the point,

perhaps even in a rather childish manner, that one particular programming language is better than

another is. But on what grounds is this being assessed? [Law97] comments that “unskilled

programmers can write bad code in any language, but a good language facilitates the production of

good code by skilled programmers.” Defining the properties of a good programming language also

makes it possible to examine the relationship between ‘good’ and ‘safe’ programming languages.

[Law97] describes a number of criteria for a good programming language.

• “Its definition should be independent of any particular hardware or operating system.”

Portability can be compromised if a language is not independent of a particular platform. This

is likely to limit the hardware and software options both for the original system and for future

upgrades.

• “Its definition should be standardised, and compiler implementations should comply with the

standard.” Unique solutions can result if compiler implementations do not comply with the

standard language definition.

• “Its compiler implementations should be commensurate with the current state of technology.”

In addition the compiler implementation should match the current language standard if the

language has been standardised. A compiler that does not meet these criteria may produce

substandard code. It may not also implement key language features.

• “It should support software engineering technology, discouraging or prohibiting poor

practices, and promoting or supporting maintenance activities.” Poor code characteristics can

lead to extended development times. In addition this can make both testing and maintenance

difficult.

• “It should effectively support the application domain(s) of interest.” Poor support for the

application domain may make the development of a clear solution difficult. This can also

have an impact on performance characteristics of the code.

• “It should support the required level of system reliability and safety.” The system is likely to

perform below expectations if the reliability is less than desired. It is also likely to become

much more costly across its lifetime. Human life and property can be at risk if safety is

compromised.

• “Appropriate software engineering-based support tools and environments should be

available.” Developer productivity and system quality can be compromised if there is a lack

of appropriate tool support.

[Law97] also describes language specific characteristics that are important. These are described in

Table 1 along with the associated ratings for numerous languages. The intention is that for a given

application a weighting is determined based on which language characteristics are deemed most

important. These weightings are then factored into an overall rating for each language. This rating

can be then used to assess the languages which are most suitable for the given application.

Page 23: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16

Language Generation 3GL 2GL

Language Characteristic

Weig

ht

4GL

or

5GL

Ada95 C

C++

COBOL

FORTRAN

Java

Smallta

lk

Assem

bly

Clarity of source code 5 9 5 6 7 5 8 9 1

Complexity management 2 9 5 6 2 4 7 6 2

Concurrency support 0 8 0 0 0 0 7 2 2

Distributed system support 0 5 0 0 0 0 7 0 0

Maintainability 5 9 2 7 2 2 9 7 0

Mixed language support 0 8 5 7 0 5 5 3 0

Object-oriented programming support 0 10 0 10 0 0 10 10 0

Portability 1 8 5 7 3 3 9 3 1

Real-time support 0 7 7 7 0 5 0 0 5

Reliability 3 9 1 5 3 1 8 3 0

Re-useability 1 8 3 8 3 3 8 8 1

Safety 0 6 0 3 0 0 4 0 0

Standardisation 1 10 5 5 5 5 8 3 0

Support for modern engineering methods 3 9 1 7 1 1 9 7 0

Overall Language Rating

Table 1: Ratings of Language Characteristics [Law97]

Interestingly, [Law97] has identified that safety is a key feature of a good programming language.

But it is also just one of fourteen characteristics, and thus for most non-safety critical applications

its influence is likely to play little role in determining the language selection. Interesting, there

seems to be less focus on safety for 4GL and 5GL languages. [Law97] defines that a measure of the

safety of a programming language is the “extent to which inherent language features support the

construction of safety critical systems, yielding systems that are fault-tolerant, fail-safe, or robust in

the face of systematic failures.” Reflecting on this in relation to the language criteria shortly to be

expressed in Section 2.2.3 indicates that design also plays a role in safety. Finally it should follow

that a programming language for safety critical systems should be strong with respect to this safety

definition, but to be practical it should also satisfy a significant proportion of the good

programming language features.

[Law97] also identifies software-engineering considerations that also play a role in language

selection. A further means of refining the language selection is presented in [Law97] based on the

following factors.

• Method and Process

• Metrics and Measurement

• Application Domains

• Software-Reuse

• Re-engineering

• Development Environment and Tools

• Education and Training

Thus it is evident that a good language is not merely considered the sum of its characteristics. In

addition the external environment in which the language is applied also plays a critical role in the

language’s fitness for purpose.

2.2.2 Choice of Programming Languages for Use in Safety-Critical Systems

Section 2.2.1 examined the criteria for a good programming language, noting that such a definition

is always impacted upon by the context of the application. For safety-critical software the context is

the safety critical system. For example, it was earlier highlighted that [MoD97] states that safety

Page 24: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

17

critical software is “software that relates to the safety critical function or system, ie. software of the

highest safety integrity level (S4), the failure of which could cause the highest risk to human life.”

There are a number of factors to consider when considering a language for a safety critical system.

• Language choice: including the functional characteristics [Sto96], logical soundness and

simplicity [Bar02], expressive power [Bar02], security [Bar02] and standardisation [Hat94].

• Availability of compile-time checking and run-time checking [Dou98];

• Exceptions versus error codes [Dou98];

• Bounded space and time requirements [Bar02];

• Use of ‘safe’ language subsets [Dou98];

• The availability and quality of support tools [Sto96]; and

• The expertise available within the development team [Sto96].

Some programmers, especially those working with embedded applications, dismiss run-time

checking because of the performance overhead. Though perhaps a safe design should cater for this

performance overhead by specifying appropriately resourced hardware. [Dou98] points out that a

programmer should “make it right before you make it fast.” In considering these factors, it is also

worth considering if some programming features are more prone to problems than others. [IPL96]

details a number of reasons why some programming language features are more prone to problems

than others:

• Programmers may be prone to making errors when using the feature;

• Compilers may be prone to poor or incorrect implementation of the feature;

• Programs written using the feature may be difficult to analyse, test or prove; and

• The feature may introduce implementation dependencies, reducing portability.

[IPL96] also details a number of specific language features which are prone to causing problems

and discourages their use:

• Pointers

• Dynamic Memory Allocation and

De-allocation

• Unstructured Programming

• Variant Data

• Procedural or Function Parameters

• Multiple Entry and Exit Points

• Implicit Declaration and Implicit

Initialisation

• Recursion

• Concurrency and Interrupts

[Hat94] also defines characteristics of languages relating to empirically determined behaviour.

These parts of the language are typically well defined, but seem to cause problems. In addition the

abuse may not be obvious.

Page 25: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

18

• Errors of Misplacement: relates to instances whereby semantically correct portions of code

are placed in the wrong place within a block structure, and thus resulting in behaviour that

may be unpredictable.

• Errors of Omission and Addition: relates to instances whereby the omission or addition of a

symbol or character results in another legal but unintended language construct. Some

languages combat such problems by creating language symbols that are not closely related.

• Floating Point Misbehaviour: relates to the indeterminate behaviour that often arises when

comparing floating point numbers.

• Unexpected Behaviour: relates to those features of the language that although legal do not

follow assumed language conventions, or are frequently misunderstood by programmers. A

common example of such a feature is the evaluation order and precedence within expressions.

Despite the rather long list of traps that it would seem there are for programmers to fall into,

[IPL96] also states however that “in some circumstances the careful and constrained use of features

such as multiple exits, pointers, recursion, concurrency and interrupts, can actually reduce

complexity and enhance reliability.” [IPL96] also describes a number of features of languages that

also increase reliability. These include:

• Strong Typing

• Run-Time Constraint Checking –

including Arithmetic Exceptions,

Overflow, Validity of Pointer Addresses,

or Array Bounds.

• Parameter Checking

• Block Structure and Modular

Programming

[Dou98] also suggests that strong compile-time checking, support for encapsulation and abstraction,

and exception handling are features that increased reliability. Noting of course the earlier

differences in the definition of reliability and safety.

In an effort to formalise the selection criteria for a safe language, [Cul91] identifies a list of

questions that should be addressed when choosing a language:

• Can the control flow be totally determined and that the program cannot jump to an arbitrary

location (ie. there are no wild jumps)?

• Are there language features that prevent overwrites of an arbitrary storage location?

• Are the semantics of the language sufficiently defined for the translation process such that

static code analysis is feasible?

• Is there a rigorous model of mathematical operations (ie. integer and floating point

arithmetic) in the language standard?

• Are there procedures for checking that the program obeys the model of arithmetic when

running in the target environment?

• Are there sufficient means of preventing misuse of variables through strong data typing?

• If the software detects a malfunction at run-time, are there mechanisms (ie. exception

handlers) to ensure recovery?

Page 26: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

19

• Does a safe subset of the language exist which is defined to have properties that satisfy these

requirements more adequately than the full language?

• Are there facilities in the language to guard against running out or the exhaustion of memory

at run-time (eg. to prevent stack and heap overflows)?

• Does the language provide facilities for the separate compilation of modules, with type

checking across the module boundaries?

• Is the language well understood by programmers and designers to ensure confidence in the

resultant software?

[IPL96] states that “there are no commonly available programming languages which provide all of

the good language features, while not providing any of the bad language features.” [IPL96] then

proposes that the means of reducing the impact of the bad language features is to use a language

subset. A subset then consists of using the good features of a language, while the bad features are

either not included or their impact is controlled [IPL96]. For some languages the subset may simply

be a subset of the language’s grammar, for others the subset may also need to address features and

functionality of the language. The use of the subset will either require the programmers to be

disciplined in their use of the language. Alternatively, and perhaps more desirably is to use software

tools to enforce the language subset. Though, generalised rules may pose problems to this approach.

[Hat94] defines a number of areas relating to specific language features that should at the very least

be mitigated or controlled when defining a safe language subset. The aim is to ensure that the

language subset has a defined, predictable behaviour.

• Unspecified or Undefined Behaviour: relates to legal (and illegal) language features about

which the standard declines to specify;

• Implementation-Defined Behaviour: relates to language features whose implementation,

although defined, is allowed to vary from implementation to implementation;

• Locale Specific Behaviour: relates to issues that are region or equipment specific; and

• Accidentally Defined Behaviour: relates to language features that exhibit strange behaviour

because the standardisation committee was ‘having a bad day’.

A comparison of computer programming languages described in [Sto96] shows that a subset

provides a considerable safety improvement when compared to the its parent language. It is for this

reason that [Sto96] states that “subsets … are preferred for all safety-critical applications.” Of

course, the safety case for the safety critical system should be then prepared to justify the choice of

the language, use of the subset, or any deviations from the subset [IPL96].

2.2.3 Requirements of Safe Programming Languages

Section 2.2.2 examines a number of factors that might impact upon the selection of a programming

language for use in the development of a safety-critical system. From these factors it is possible to

go about defining the criteria for assessing if a programming language can be deemed to present the

least risk to correctly implementing the design.

[Kwo03] summarises from numerous sources, including some of those covered in Section 2.2.2,

and proposes a set of requirements of programming languages for the development of high integrity

systems. [Kwo03] states “it is important to note that that this collection of criteria is neither

Page 27: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

20

complete nor authoritative, but it attempts to amalgamate many different requirements into a

balanced and informative framework for the assessment of programming languages.” An inspection

of the criteria defined by [Kwo03] against those defined in Section 2.2.2 reveals that [Kwo03] is

comprehensive. It incorporates essential safety criteria, but also reflects other characteristics of

good programming languages including reliability. Thus a set of criteria is established. It is

important to note that the criteria does not explicitly list any paradigm (eg. object-oriented) criteria.

Instead it sets about defining the general goals that should be achieved. Object-oriented restrictions

to support these criteria are examined in Section 2.4.

[Kwo03] proposes two levels of criteria for an assessment of programming languages: Mandatory

Requirements (M) and Desirable Requirements (D). The following sections explain the criteria.

2.2.3.1 Syntactical / Semantic Requirements (M)

• Type Safety / Strong Typing Rules: Implicit type conversions must not be allowed as they

detrimentally influence the level of program safety [Kwo03]. Type conversions are known to

influence the safety of control flow, and the use of memory (stack, heap). In addition, all data

types (including user specified types) should be analysable prior to the program being

executed (eg. statically at compile-time) [Kwo03]. Such a characteristic is often reflected in

type safe or strongly typed languages. Many languages define explicit type conversion rules

or operators. These should be clearly specified within the language standard or definition

[Kwo03]. They should be used judiciously and only when absolutely necessary. The language

should also include means of avoiding access types or pointers [Kwo03].

• Side Effects in Expression / Operator Precedence Levels / Initial Values: There should be no

side-effects of expressions (time-dependant or otherwise) that can result in a program

behaving ambiguously or unpredictably [Kwo03]. The operator precedence levels must be

unambiguously defined in the language standard or definition [Kwo03]. The implicit

initialisation of variables should not be permitted as it can cause the unintended behaviour of

software [Kwo03].

• Modularity / Structures: In order to ensure the complexity of the software is manageable, the

language should include mechanisms to structure and modularise the code both syntactically

(blocks and scopes) and semantically (clear interfaces) [Kwo03]. Wild or unbounded jumps

between scopes or modules should be disallowed. [Kwo03]. Separate compilation of modules

should be possible [Kwo03].

• Formal Semantics / International Standards: The language should be defined in an

(international) standard such that the benefits of the development of compilers, tools and user

training can be harnessed [Kwo03]. The definition should include the sufficient formal

definition of semantics such that verification techniques can be applied to the language

[Kwo03].

• Well-understood: In order to best facilitate the correct implementation of a programming

solution the programming language should be simple, well understood, easy to adopt, and

easy to implement [Kwo03]. Well-understood semantics and syntaxes can also help in the

production of quality, cost effective software [Kwo03].

• Support for Domain Specific or Embedded Applications: As safety critical systems are often

implemented in terms of embedded systems, then the language needs to have a robust means

for controlling memory, I/O devices and other hardware [Kwo03].

Page 28: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

21

• Concurrency / Parallel Processing: The language should include support for multi-tasking or

multi-threading to ensure that it can easily be used to model real world problems [Kwo03].

The language should facilitate the programmer some control over the scheduling as well as

one or more means for straightforward communication and synchronisation between

tasks/threads [Kwo03]. Concurrency brings with it a number of complexities in program

analysis and verification and as such mechanisms should be available within the language to

bound complexities such as blocking [Kwo03].

2.2.3.2 Application of Verification Techniques / Predicability (M)

• Functional Predicability: Software for use in safety critical systems must be proven to be

functionally predictable in its behaviour [Kwo03]. The following analysis techniques are both

applicable and necessary: control flow analysis, data flow analysis, information flow analysis,

symbolic execution, and formal code verification [Kwo03].

• Temporal Predicability / Timing Analysis: In addition to functioning correctly, programs

should also be able to guarantee a predictable, timely behaviour [Kwo03]. It must be possible

to determine a Worst Case Execution Time (WCET) for each process such that all aspects of

schedulability can be analysed [Kwo03].

• Resource Usage Analysis: The uses of resources such as memory (stack or heap), and other

resources shall be analysable [Kwo03]. The use of such resources shall be such that errors

shall not occur [Kwo03].

2.2.3.3 Language Processors / Run-time Environment / Tools (M)

• Certified Language Translators / Run-time Environments: The compilers and other tools used

in the translation of the program code into machine code play a critical role in ensuring the

safety of the software. Thus they need to have a high level of assurance associated with them

[Kwo03]. Compilers and other tools (including run-time environments) should be formally

certified by an authoritative or trusted organisation [Kwo03]. Traceability should be

established between low level code and source code [Kwo03].

• Run-time Support / Environment Issues: Libraries (and other additional code) should be

deterministic, predictable and analysable in terms of functionality, behaviour and timeliness

[Kwo03]. These factors should be accurately known if the library is to be included. The

implementation dependencies should be eliminated where possible, and minimised where

necessary [Kwo03].

2.2.3.4 Syntactical / Semantic Requirements (D)

• Exception Handling / Failure Behaviour: The graceful degradation or recovery from any sort

of error that occurs is considered important particularly for safety critical systems. As such,

[Kwo03] specifies that a “robust and analysable run-time error detection and handling

mechanisms should exist.” Furthermore, there should be a means by which the programmer

can specify the failure behaviour [Kwo03].

• Model of Mathematics: The mathematical model within the language should be rigorously

defined [Kwo03]. Specifically, [Kwo03] states that “a model of both integer and floating

point arithmetic should be defined within the language standard.” In addition, some level of

checking of arithmetic should occur at run-time [Kwo03].

• Support for User Documentation: Comments embedded with the software can improve

readability and maintainability [Kwo03]. Furthermore some language processors may be able

Page 29: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

22

to detect logical errors or to obtain extra information from formally structured comments and

as such [Kwo03] specifically details that the language should include a means of capturing the

programmers intentions within the comments of the source code.

• Support for a Range of Static Types Including Sub-types and Enumeration Types: Dynamic

types are more difficult to check than static types [Kwo03]. Enumeration types can also help

reduce errors by limiting the number and value that a given type can be legitimately assigned.

• Coding Style Guidelines: Coding style guidelines work to enforce the practice of

programming in a particular language by promoting conformance to well-established software

engineering principles [Kwo03].

• Support for Abstraction and Information Hiding: The employment of abstraction and

information hiding techniques is considered good software engineering practice. Such

techniques can help reduce the apparent software complexity and these can also be beneficial

in software design, development, testing and maintenance [Kwo03].

• Assertion Checking: User defined assertions can be used to check specific conditions. These

may be checked statically during development (compile-time). Alternatively, the assertions

may be checked dynamically during execution (run-time). While the means of defining and

dealing with assertions both statically and dynamically may vary, both are considered

desirable characteristics of a language [Kwo03].

2.2.3.5 Language Processors / Run-time Environment / Tools (D)

• Certified (Static/Dynamic) Analysis Tools: Analysis tools can be used to check for errors such

as race conditions and deadlocks [Kwo03]. In order to gain confidence in the results of such

analysis, it is imperative that these tools be certified to some degree.

• Interface to Other Languages: The language should include a means of interfacing functions

or libraries written in other programming languages to programs written in this language

[Kwo03]. These functions and libraries may have been developed in other high level

languages, however there is often a requirement to also interface functions or libraries written

using low level languages.

• Code Optimisation: There are numerous means and tools that can be used to optimise

software code and thus improve the efficiency of the code. These optimisations should not

“alter the semantics of correct programs”, likewise they should not “compromise the

application of analysis techniques” [Kwo03].

• Code Portability: The diversity of platforms on which software may execute makes it

desirable to have software code that can be directly portable without necessitating subsequent

analysis [Kwo03].

2.3 Programming Languages and Safety Standards

The certification of safety critical systems often requires the use of appropriate standards and

guidelines. Safety standards are often particular to industry or government sectors, engineering

disciplines, or a combination of both. The following sections examine a number of standards that

are considered to be the most relevant to software in the safety critical domain. Note that there are

other safety standards that relate to software, but these will not be specifically examined here. The

intention is to establish an understanding of the programming language (and associated)

requirements of these standards such that they can be later examined in the context of the C++

Page 30: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

23

programming language. There are many common themes between the guidance presented in a

number of these standards and the language features presented in Section 2.2.2. Such a fact suggests

that there is widespread agreement on language features that can impact upon safety.

2.3.1 Safety Integrity Levels (SILs)

Firstly, because a number of the standards deal with Safety Integrity Levels (SILs), it is worth

defining them. SILs are often the source of much confusion and thus it is worth firstly clarifying a

few important points. The purpose of SILs is to define a set of levels that corresponds to a

probability figure (or range) representing the required level of protection against failure. Depending

on the standard in which the SIL is defined this may be a qualitative or quantitative value. This

safety integrity level is then used to guide the formation of the development processes and controls.

Guiding factors include the degree of rigour and scrutiny to be applied.

Numerous safety standards refer to SILs. IEC 61508 [IEC98] and Defence Standard 00-55

[MoD97] refer to SILs of levels 1 to 4, with 4 being the level of the highest integrity. In contrast,

RTCA/DO178B [RTC92] defines software levels A to E, with A being the level of the highest

integrity.

It is important to recognise that the definition of the various integrity levels can vary between

standards and the reader should refer to the specific standard for the appropriate definition. One can

not simply directly convert from one integrity level in one standard to the corresponding level from

another standard. Instead, the specific requirements of the standard needs to be assessed against the

techniques and methods applied to the given project.

2.3.2 IEC 61508 – Functional Safety: Safety Related Systems

IEC 61508 addresses the functional safety of electrical/electronic/programmable electronic safety-

related systems. The standard is considered an international standard and is not specific to a single

industry (ie. it is a generic standard). The intention is that the standard will form the basis on which

other industry specific standards will be built [Sto96]. The standard adopts a risk based approach to

the determination of safety level requirements. Part 3 of the standard specifically relates to software.

In addition, Annex C of Part 7 of the standard gives an overview of techniques and measures for

achieving software safety integrity. The requirements of this standard are by far the most detailed

and prescriptive of either of the other standards considered. In fact [Hat94] points out that the draft

to this standard was the “most comprehensive assessment of the requirements for safety-related

software” that had been seen at that time.

[IEC98] details that the programming language shall:

• “have a translator/compiler which has either a certificate of validation to a recognised national

or international standard, or it shall be assessed to establish its fitness for purpose”;

• “be completely and unambiguously defined or restricted to unambiguously defined features”;

• “match the characteristics of the application”;

• “contain features that facilitate the detection of programming mistakes” and

• “support features that match the design method”.

[IEC98] goes on to state that should the above not be able to be satisfied, then a justification for an

alternate language shall be documented, in which controls for the shortcomings of the language are

identified. The following tables extracted from [IEC98] represent the most significant specific

Page 31: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

24

guidance given in relation to the selection of the programming language. The reader is encouraged

to refer to [IEC98] for specific descriptions of each of the items presented, as it is not the intention

to reproduce the material here. Table 2, Table 3, and Table 4 details the most relevant guidance on

programming languages presented in [IEC98]. Each technique or measure in Table 2, Table 3, and

Table 4 is annotated with a recommendation for safety integrity levels 1 to 4. These

recommendations are as follows.

• HR: “the technique or measure is highly recommended for this safety integrity level.”

• R: “the technique or measure is recommended for this safety integrity level as a lower

recommendation to a HR recommendation.”

• ---: “the technique or measure has no recommendation for or against being used.”

Table 2: Support Tools and Programming Language – Part 3, Table A.3 [IEC98]

Table 3: Detailed Design – Part 3, Table A.4 [IEC98]

Page 32: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

25

Table 4: Design and Coding Standards – Part 3, Table B.1 [IEC98]

The programming language should also provide for a block structure, translation time checking, and

run-time type and array bound checking [IEC98]. In addition the language should encourage the use

of small and manageable software modules, restriction of access to data in specific software

modules, definition of variable sub-ranges, and any other type of error limiting constructs [IEC98].

If there are real-time constraints, then the language should also provide exceptions/interrupt

handling. Table 4 is a little unique in [IEC98] as it uses the terminology ‘no’ or ‘limited use of’ to

prohibit potentially dangerous language features. Other tables in [IEC98] recommend rather than

limiting the use of techniques.

[IEC98] also provides recommendations for specific programming languages. This advice covers

Ada, Modula-2, Pascal, and Fortran 77, including subsets of each of these to name but a few. The

standard also highly recommends C with subset and coding standard, AND use of static analysis

tools [IEC98]. Importantly [IEC98] does not specifically advocate C++, nor does it prohibit it.

Interestingly, [IEC98] states that “at the time of developing this standard, it is not clear whether

object-oriented languages are to be preferred to other conventional ones.”

2.3.3 RTCA/DO178B – Software Considerations in Airborne Systems

RTCA/DO-178B was written to address a rapid increase in the use of software in airborne systems

in the civilian aviation sector. The standard is aimed at manufacturers seeking certification by their

relevant aviation authorities.

RTCA/DO-178B details that the manufacturer should have software code standards to define the

programming languages and/or defined subset, methods, rules and tools to be used to code the

software [RTC92]. “For a programming language, reference the data that unambiguously defines

the syntax, the control behaviour and side-effects of the language” [RTC92]. [RTC92] also suggests

that there may be a requirement to limit the use of some features of the language, but does not go

into how this might be achieved. There is no specific mention of particular programming languages,

and as such the standard does not prohibit the use of any languages.

RTCA/DO-178B also details that the manufacturer should have software design standards. These

are pretty closely related to the software code standards mentioned above in that the design

standards are used to define the methods, rules, and tools to be used to develop the software

architecture and low-level requirements [RTC92]. [RTC92] details that conditions should be placed

on scheduling, the use of interrupts, event driven architectures, dynamic tasking, re-entry, global

data, and exception handling. In addition, the constraints should be placed on the design including

the exclusion of recursion, dynamic objects, data aliases, and compacted expressions. [RTC92] also

defines a number of complexity restrictions including the maximum level of nested calls or

Page 33: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

26

conditional structures, use of unconditional branches, and number of entry/exit points. The standard

also addresses issues such as naming conventions, stylistic issues, and the use of design, translation,

and coding tools. The standard does offers some guidance on the use of the programming language

and the verification and use of the compiler [RTC92].

Largely the standard relies on engineers taking a disciplined approach to software. Because of this,

[Hat94] criticises RTCA/DO178B for avoiding software measures and for not mandating

quantitative terms for evaluating software reliability. However, [Sto96] references a report that

concludes that RTCA/DO178B is a mature standard that has much to recommend it.

RTCA/DO178B is widely used throughout the international community despite its age. Thus there

are likely to be many manufacturers that may be interested in the certification of systems

programmed using C++ in relation to the standard.

2.3.4 Defence Standard 00-55 – Safety Critical Software in Defence Equipment

Defence Standard 00-55 Issue 2 addresses requirements for safety related software in defence

equipment for the United Kingdom’s Ministry of Defence (MoD).

[MoD97] details that the software should be programmed using a high level language or a pre-

defined subset of a high level language. The language should be strongly typed, block structured,

have a formally defined syntax, and exhibit predictable program execution [MoD97]. Furthermore,

[MoD97] specifies that the choice of programming language shall be justified in the Software

Safety Case. Coding practices should also be established, and in the case where a language subset is

utilised, then it should be defined and the means of enforcing it should also be addressed.

[MoD97] also details that the semantics of the language need to be well defined and that both static

and dynamic checks are required. The language should also be traceable between the formal design

and the execution of statements in the language. [MoD97] describes that this can be achieved if the

language has accepted formal semantics and a proof theory in terms of the formal method in use or

in terms of a proof obligation generator. [Sto96] points out that this standard sets itself apart from

the other standards examined here in that it mandates the use of formal methods.

The only exception to the stipulated use of high level languages is for limited use of assembly code

in sections of the code where high level languages are not suitable or in very small applications

[MoD97]. There is no stipulation of specific languages, though Ada is mentioned briefly in some of

the latter application and techniques examples in Part 2 of the standard.

[MoD97] suggests that at lower SILs, language selection criteria other than integrity alone may

have a greater influence than at higher SILs. For example tool support, performance and portability

may be more desirable criteria. [MoD97] also provides some guidance on the selection of use of the

compilation and tool sets.

It should be noted that at the time of writing this report, the draft Defence Standard 00-56 Issue 3

[MoD04] states that it supersedes Defence Standard 00-55 Issue 2. Defence Standard 00-56 Issue 3

is a goal based standard, not a prescriptive standard as was 00-55 Issue 2. Some references are made

to the choice of programming languages in relation to the demonstration of good practice, and the

selection of evidence types. Rather than prescriptively mandating certain languages or language

characteristics, the standard leaves the justification of the language’s safety to the developers of the

safety case. Thus the developers must present a justifiable argument for the language selection and

there is scope for a means to be examined through which this can be achieved. This is further

explored in Section 2.8.

Page 34: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

27

2.4 Object-Oriented Technology in Safety Critical Systems

Section 2.2.3 mentions that the language paradigm was only covered by the language criteria as far

as its contribution to the other criteria. Thus there is motivation to consider how the paradigm, and

particularly how object-oriented programming, might contribute to these criteria. Object-oriented

programming has grown into an immensely popular programming paradigm in recent times.

Modern languages including Ada95, C++, and Java all contain object-oriented features. To date,

there has been little application of the object-oriented paradigm to safety-critical applications,

though it is presently the focus of much attention. The following sections examine some of the

problems surrounding object-oriented programming in safety critical systems, as well as current

guidance on mitigating these problems.

2.4.1 Concerns Over Object-Oriented Technology in Safety Critical Systems

In a similar theme to those features of traditional programming languages that are known to be error

prone, there are also numerous challenges relating to the object-oriented paradigm. The challenges

of using object-oriented technology within safety critical systems that require rigorous verification

and certification are non-trivial [Bar02]. “The object-oriented model severely conflicts with the

highly static model that is required in high integrity systems to meet the goals of time and memory

boundedness assurance, and of determinism in data transformation due to code operation.” [Bar02].

The following sections now examine some of the principle concerns.

2.4.1.1 Constructors and Destructors

The creation and destruction of objects has the potential to impact upon being able to statically

prove the time and memory constraints of a given system (ie. the lifetime of an object should be

able to be statically determined by the scope in which it is created) [Bar02]. For example, there are

issues relating to the need to create objects in dynamically-allocated memory that can result in

associated non-determinism regarding heap fragmentation, exhaustion and compactions, as well as

unbounded heap allocation times [Bar02]. In addition the correct initialisation (construction) of an

object is also important. Garbage collectors that are used in numerous object-oriented languages

introduce overheads and unpredictability into the finalisation of objects [Bar02].

2.4.1.2 Hierarchy and Inheritance

Interface contracts can be violated if a subclass operation overrides an operation in a superclass and

then fails to conform to the original pre-conditions and post-conditions of the superclass operation

(Liskov/Wing substitution principle) [Bar02]. In fact [Bar02] points out that the major risk of

inheriting operations is “not understanding the pre-conditions associated with the use of the

operation, and not abiding with those pre-conditions in the context of the subclass.”

Multiple inheritance also introduces problems both in terms of ambiguity of semantics and of

implementation complexity.

2.4.1.3 Polymorphism and Dynamic Dispatching

Polymorphism and dynamic dispatching undermine certain aspects of static analysis [Bar02]. This

is because the actual object that is represented by a polymorphic object can only be determined at

run-time. This interferes with data and information flow analysis [Bar02]. In addition control flow

analysis can be undermined because the operation to be called by dynamic dispatching is only

known at run-time [Bar02]. These issues do not only undermine static analysis, they also impact

traditional testing methods also. [Bar02] also highlights that polymorphism and dynamic

dispatching also impact upon schedulability and response time analysis, model checking and object-

code coverage analysis.

Page 35: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

28

2.4.1.4 Obscurity

[Bar02] states that “the creation of large class hierarchies can result in obscurity in determining the

provenance of an inherited operation at the point of call.” In addition, inheritance may also hide

from users restrictions and implicit semantics of particular operations [Bar02].

2.4.1.5 Dead-code/Deactivated Code

[Bar02] describes that object-oriented programs are very susceptible to generating deactivated code.

When all subclasses that inherit a particular superclass override a given operation, then it is possible

that there may be no instances of calls to that superclass operation in a program. Thus, while this

operation’s code is still resident with the object, this code may never called and thus constitutes

dead or deactivated code. Because is may never be called, it is unlikely and difficult to test and thus

it may be difficult to gain confidence that it cannot have any impact on run-time behaviour of the

program. For a system where there are many fully overridden operations, then this has a major

impact on reaching code coverage targets.

2.4.2 Handbook for Object-Oriented Technology in Aviation (OOTiA)

There has been some effort made to address the problems described in Section 2.4.1 across the

aviation community. The Handbook for Object-Oriented Technology in Aviation (OOTiA) is

presently in draft form for public comment. The purpose of the handbook is to “identify key issues

and provide some ways to address these issues when using OOT in safety critical aviation products”

[OOT04]. It specifically attempts to address compliance with the objectives of RTCA/DO-178B

which was not written with object-oriented technology in mind [OOT04]. The handbook is the

result of the collaboration of the FAA, National Aeronautics and Space Administration (NASA),

other government organisations, academia, international certification authorities, avionics

manufacturers, and aircraft manufacturers. It is important to note that the handbook does not

constitute FAA policy or guidance, and nor is it intended to be an endorsement of OOT [OOT04].

[OOT04] presents guidelines in the following key areas:

• Single Inheritance and Dynamic Dispatch

• Multiple Inheritance

• Templates

• Inlining

• Type Conversion

• Overloading and Method Resolution

• Dead and Deactivated Code, and Re-Use

• Object-Oriented Tools

• Traceability

• Structural Coverage

Given the breadth of government, industry and intellect that has contributed to the production of the

handbook, it is likely that it represents a comprehensive and accurate examination of issues relating

to object-oriented technology at this time. The handbook is yet to address language specific issues.

Thus it would be worthwhile to explore the OOTiA guidelines within the specific context of the

C++ programming language.

2.5 C in Safety Critical Systems

Because the C programming language is a subset of the C++ programming language, it is

worthwhile to explore the use of C in safety-critical systems. The intention is to seek an

understanding of some of the issues that may also relate to the C++ language.

Page 36: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

29

An informal survey conducted by [Row94] examined the use of languages in safety-critical projects

across a number of industries. The survey made no distinction between different levels of integrity,

nor did it identify the specific use of any language subsets [Sto96]. [Row94] points out a number of

safety-critical projects that used C and these are as follows. Note that this survey is now ten years

old and that the use of the language has most certainly changed since then.

• Aviation and space applications – including Honeywell’s aircraft navigation data loader, some

sub-systems of the NASA space station, some systems developed by Rockwell Space Systems

Division, and Teledyne’s aircraft flight data recorder;

• Numerous automotive systems – the release of the MISRA C guidelines in 1998 has arguably

widened the use of the language for such systems; and

• Baxter’s left ventricular heart-assist.

The C programming language is also widely used in numerous military electronic warfare software

applications, and military developmental flight test establishments.

[Cha04] points out that great care needs to be exercised when using C within safety critical systems.

In fact [MIS98] details a number of concerns and problems relating to its use and thus concludes,

“the full C language should not be used for programming safety-related systems.” However

[MIS98] also points out the language is very mature, and well analysed and supported in practice.

Thus [MIS98] reasons that with appropriate constraints, then the language can be applied to safety-

critical systems. [MIS98] then provides a set of such constraints (ie. a subset) for the C language

that is otherwise known as MISRA C. This subset consists of required and advisory rules. All of the

provisions described in [MIS98] are to be adopted for MISRA Integrity Level 2 and 3, but they

make no recommendations for MISRA Integrity Level 4.

Despite the documented examples of the C language’s presence in such systems, there is also much

opposition to its use. For example, an anonymous C expert states in [Cha04] that “MISRA C is a

shack built on a swamp.” [Cha04] goes on colourfully to say that C90 (or even C99) “is a swamp

that cannot be drained.” In addition the MISRA C rules are ambiguous [Cha04].

There have been attempts to develop an annotated C subset for the C90 programming language

(SPADE C) akin to SPARK for Ada [Cha04]. SPADE C did not succeed, nor where the results

widely publicised [Cha04].

[Cha04] argues that MISRA C cannot be deemed best practice, especially given the presence of

languages like Eiffel and SPARK. However [Cha04] also states not to “give up on MISRA C! It

may be a shack built on a swamp, but it’s the best shack you’ve got!”

The MISRA C guidelines recommend seriously considering other languages in preference to

MISRA C for safety critical software [MIS98]. In fact [MIS98] takes care to point out that they are

not trying to promote the use of the C language for such applications, but instead to promote the

safest possible use of the language.

Thus it would seem that there are problems with the C language for the highest integrity systems.

But this may not necessarily transpose onto the C++ language. Despite C being a direct subset of

the C++ language, there are also features of the C language that should not be used in well-written

C++ code. The following section now examines C++ and safety critical systems.

Page 37: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

30

2.6 C++ in Safety Critical Systems

Section 2.1.4 outlined a number of reasons that C++ may be selected as the language of choice for a

particular application. We shall now consider what use C++ has seen to date in safety-critical

systems, the motivation for using C++ for safety critical systems, and what is the likely way ahead

for using C++ in safety critical systems in the future. The following sections also examine a number

of perceptions relating to the use of C++ in safety critical systems.

2.6.1 Previous Use of C++ In Safety-Critical Systems

As mentioned in Section 2.5, an informal survey conducted by [Row94] examined the use of

languages in safety-critical projects across a number of industries. [Row94] points out a number of

safety-critical projects that used C++ and these are as follows. Note that this survey is now ten years

old and that the use of the language has most certainly changed since then, especially given the

standardisation of C++ in 1998.

• Space shuttle experiment (March 1994);

• Northrup B2 bomber control system; and

• Automotive systems (numerous, including diesel engine controls).

Thus it can be seen that at least for the cases listed above that there has been some past application

of the C++ programming language to safety critical systems. From this we may draw a number of

conclusions. Firstly, there has been some interest to see the language employed in the safety critical

field. Secondly, so far there has been no real application evidence from which to conclude that C++

is not suitable for safety critical applications.

2.6.2 Perceptions and Opinions on C++ and Safety

As few discussions on any topic are often free from perceptions and opinion it is worth now

examining some perceptions and opinions on C++ and safety. [Wic98] presents a moderated

discussion on C++. The following generic language perceptions and opinions are extracted from

[Wic98].

• The impact of the programming language is significant. Safety critical software should not be

written in languages designed for other purposes.

• The programming language must be able to be shown to represent the design.

• It is unreasonable to assume that every programmer in the language is an expert.

• Object-oriented programming languages are hard to test.

• The language should support the possibility of mathematical verification of algorithms and

implementations against requirements. Achieving the error rates required for safety critical

software requires different methods, not just the same methods with more care.

• Choosing a language because it is ‘states-of-the-art’ or because it is ‘better specified’ is too

narrower a basis for such a decision. An assessment considering all factors is the appropriate

approach.

Page 38: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

31

• Programmers can write good and bad code regardless of the language. Programmers are likely

to write higher quality software in a language they know well, using tools they know well, for

applications that they understand.

• There is little evidence to suggest that there is any correlation between safety incidents and

the programming language.

[Wic98] also presents the following C++ specific perceptions and opinions.

• It is hard to show that there are no storage leaks in a C++ program. Areas of the language

relating to the order of execution are undefined and as such it is difficult to guarantee

predictable execution. The typing in C++ is too weak. C++ is not state of the art!

• The C++ language lacks consistency owing to the fact that is was defined to contain the

features that many people wanted. It is not clear that there can be well-defined semantics for

C++.

• Before C++ can be considered there needs to be a well-defined subset, guidelines along the

lines of MISRA C produced, and improved training and education for developers. C++ is

unlikely to be the cheapest, quickest, or most successful approach.

• The tool-sets for C++ are mature, and in some cases code can be automatically generated

from specifications. The tools, knowledge base, and experience surrounding C++ gives it

tremendous advantages in many areas over other languages – advantages that translate into

safer systems. Tool sets are created for C++ before they are written for many other languages.

These tools make it easier to spot mistakes, write code with fewer bugs in the first place and

to test code.

• C++ promotes certain design considerations that assist in safety critical applications. Modular

code makes unit review and testing manageable. Integration and system testing can be easier

with well-defined objects and methods.

• C++ is a very reasonable choice for developing a safety critical system in a small house of

trusted engineers. C++ has too much of a following to be ignored.

Discussion about the suitability of C++ for use in safety critical systems is not limited to [Wic98].

Numerous other sources also debate the topic. These are as follows.

• [Law97] provides an assessment of numerous languages against a formulated set of good

language criteria (refer to Section 2.2.1). With respect to safety, C++ was rated 3/10, Java

4/10 and Ada95 6/10. It is important to note that no specific subsets were covered in the

assessment.

• [DDC04] states that "there is a huge reluctance to move to C++ and it’s not because of the

language, it’s because of the structure around the language. There are so many variants of C

and C++ … so even though you may settle on the same C++ language, the coding standards

that go with it are always different.”

• [Sto96] states that “within the safety-critical community it is generally agreed that in

applications where safety is concerned unstructured assembly language and C or C++ should

not be used.”

Page 39: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

32

• [Sto96] advises that “companies not yet committed to a programming language would be well

advised to strongly consider adopting Ada for all projects requiring a high integrity, with a

suitable subset being used for the most critical applications.” However, what about a company

or organisation that has programmers with many years of C++ experience? It is possible for

experienced programmers to re-train to a new programming language in a period of weeks.

Though arguably it may be many months before they reach the level of competency that they

had with their previous language. In addition, many programmers learn by example and it

may be unsuitable to be re-training the programmers onto the new language at the same time

or immediately preceding work on a safety critical project.

• [IPL96] suggests that C++, like C depends too heavily on pointers. Perhaps because of this

perceived dependency, [IPL96] does not consider the constrained use of pointers (ie. a subset)

within the C++ language.

From the comments presented above it is clear that there is division within the safety community of

the use of C++ for such applications. However, a number of the comments presented seem to be

motivated by ignorance of the C++ language, rather than on the merits or shortcomings of the

language itself. Many of the comments also fail to recognise that it may be possible to develop a

safer subset of C++ that is mostly free from the concerns raised. These comments shall be addressed

towards the conclusion of this report to ascertain if the work from this project has resulted in

disproving or supporting any of them.

2.6.3 Subsets of the C++ Programming Language

Some of the discussions in the previous section focussed on the use of a subset of the C++

programming language. Interestingly, [MoD97] points out that “currently all ‘real’ languages have

features which are undefined, poorly defined or implementation based. ‘Real’ languages also have

constructs that are difficult or impossible to analyse. Until a ‘safe’ language has been developed it is

inevitable that a language subset will be used …. in order to ensure that the program execution will

be both predictable and verifiable.” Also [Cul91] concluded that a “code of practice, designed to

enforce a subset of the chosen language, is an essential element when implementing safety-critical

software.”

However it is possible that for some languages it may not be possible to define a safe subset. For

example, [Mey98] describes that for C++ his initial interest was in “developing programming rules

that could be automatically enforced.” However he realised that the “majority of guidelines used by

good C++ programmers are too difficult to formalise or have too many important exceptions to be

blindly enforced by a program.” But does this prevent us from creating a workable subset? What

instead if a subset could be defined and then tools used to warn the programmer about cases where

one of these important exceptions comes into play. That way, the programmer would be aware of

the scenario and could then consciously choose to heed the tool’s warning or dismiss it with

cautious and conscious justifiable reasoning.

Numerous subsets of the C++ programming language have been defined. Though specific

subsetting in relation to safety is not widespread. For example, the subsets that were identified are

[PRG03]’s High Integrity C++ Coding Standard Manual and the Embedded C++ subset (EC++)

[ECP04]. Though technically Embedded C++’s main focus is not safety, but instead performance,

efficiency and code size. Recalling the notion to get it right before we make it fast, then EC++ is

probably not the best choice to begin with when examining safety.

The High Integrity C++ (HICPP) Coding Standard Manual is the most significant work that could

be identified in defining a safer C++ subset. This is examined in the following section.

Page 40: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

33

2.6.4 The High Integrity C++ (HICPP) Coding Standard Manual

The High Integrity C++ (HICPP) Coding Standard [PRG03] sets out to define a set of rules and

guidelines for the production of C++ code that is portable, readable, clear and unambiguous. The set

of rules and guidelines are intended to be applied to the ANSI/ISO C++ standard that is described in

[BSI03]. [PRG03] states that the guiding principles in producing the standard are “maintenance,

portability, readability and safety.”

The aim of HICPP is to enforce the current best practice in C++ development. It is based upon the

guidance presented in seven prominent C++ publications: [Str00], the C++ Standard which is also

presented in [BSI03], the first edition of [Mey98], [Mey96], [Mey01], [Hen97], and [Sut00]. Recall

that these texts were reviewed in Section 2.1.5.

There are a total of 158 rules and 39 guidelines. Due to the mutually exclusive nature of a number

of the rules and guideline, the intention is that only a subset of the rules and guidelines given by

[PRG03] be selected (ie. a subset of the subset). Each rule or guideline lists a brief justification for

its inclusion, as well as any exceptions to the rules and references to any texts that motivated the

inclusion of the rule or guidelines. They are grouped into the following categories.

• General: relates to management of the standard and compiler configuration (1 rule and

1 guideline);

• Class: relates to class protection mechanisms, constructors, assignment operators and

destructors, inlining, constant class members, conversion operators, inheritance, object

oriented design, and operator overloading (40 rules and 6 guidelines);

• Complexity: relates to limiting excessive complexity and number of static program paths

(3 rules);

• Control Flow: relates to ensuring intended control flow structures, boolean expressions, wild

jumps, and entry and exit points (11 rules and 1 guideline);

• Constants: relates to effectively using constants, and preventing misinterpretations of

constants (5 rules and 1 guideline);

• Conversions: addresses conversion and casting issues (7 rules and 1 guideline);

• Declarations and Definitions: relates to the structure, scope, language restrictions of variable,

type and object declarations and definitions (14 rules and 10 guidelines);

• Exceptions: relates to dealing with the C++ exception handler, including throwing and

catching exceptions (3 rules and 3 guidelines);

• Expressions: relates to the general use of expressions, including layout, precedence, and

operators (18 rules and 3 guidelines);

• Functions: relates to naming conventions, namespaces, pass by reference and pass by value,

const types and references, return values, inlining, and overloading (9 rules);

• Memory Management: relates to overloaded functions, new and delete (8 rules);

• Portability: relates to avoiding implementation defined behaviour (5 rules and 2 guidelines);

Page 41: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

34

• Pre-processor: relates to commenting, character specifics, text alignment, conditional

compilation and file inclusion, macros, digraphs and trigraphs (14 rules and 4 guidelines);

• Structures, Unions and Enumerations: relates to variant structures, values of enumerators, and

casting. (4 rules);

• Templates: relates to template conversions, conflicts, and their appropriate use (3 rules and

1 guideline); and

• Standard Template Library (STL): relates to using the STL containers and associated features

(14 rules and 7 guidelines).

Interestingly, the number of rules is significantly greater when compared to the MISRA C standard

that defined 127 rules for that subset. Perhaps this reflects the greater complexity of object-oriented

programming languages.

In order to make it possible to avoid known problems with C++ and thus reduce the incidence of

errors, the requirements detailed by [PRG03] express:

• “Restrictions on the use of the language constructs or library functions that are not completely

defined by the ISO C++ Standard”;

• “Restrictions on language constructs that permit varied compiler interpretation”;

• “Restrictions of the use of the language constructs or library functions that are known to be

frequently misunderstood or misused by programmers thereby leading to errors”; and

• “Restrictions on the use of language constructs that inhibit the capabilities of static analysis”.

Figure 5 presents a graphical representation of the impact of subsetting on the C++ language.

Figure 5: Defined Safer C++ Subset [PRG03]

While Figure 5 is certainly accurate it fails to capture a number of important issues relating to

subsetting the C++ language. A better way to convey the meaning of an safer C++ subset is as

follows (Figure 6). Firstly the C++ grammar must be limited to restrict keywords that lead to unsafe

behaviour. However it should be noted that due to the many behaviours of the C++ language, a

limitation in the grammar alone is not sufficient to satisfy our requirements for a safe subset. Thus

within the limited grammar, the functionality or features must also be limited to a subset of those

that are well-defined. In some cases this requires the explicit use of C++ key-words to appropriately

define the behaviour. Thus only through these restrictions can we hope to arrive at a safer C++

Page 42: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

35

subset whose constructs are well defined, singular in contextual interpretation, well understood and

compatible with rigorous static analysis.

Scope of

ISO C++

Defined, safer

subset of

ISO C++

grammer and

features

Subset of

ISO C++

grammer

Figure 6: Better representation of a Safer C++ Subset

Given the strong ties between HICPP and C++ best practice, there is little value in attempting to re-

invent another C++ subset. Instead it is worthwhile for this project to explore just how safe HICPP

is, and what (if required) else needs to be done to allow the use of C++ for safety critical systems.

In addition, given the number of rules and guidelines, it is clearly beyond expectation of a typical

programmer to be able to self-discipline oneself such that the rules can be followed. Thus it is also

worth exploring the availability and use of tools to support this activity.

2.7 Alternatives to C++ in Safety Critical Systems

[Cha04] discusses alternatives to MISRA C and quickly dismisses C++: “No! Please don’t go

there!” Real-Time Java receives similar treatment. Eiffel receives some praise from [Cha04] in that

it is a good language design, but unfortunately it is not suitable for small, embedded hard real-time

systems. [Cha04] them moves on to consider Ada95. [Cha04] states that it is “Excellent, but full

language is too large.” Ada is the preferred language for the implementation of safety critical

software because it can be used effectively within the constraints identified by [IPL96].

[Cha04] proposes SPARK, the SPADE Ada Kernel, as a high integrity subset of Ada95 that is

suitable for high integrity, small, embedded, and hard real-time systems. The SPARK annotations

help to enforce a design-by-contract methodology and also enable comprehensive and efficient

static analysis [Cha04]. Importantly [Cha04] states that “SPARK is entirely unambiguous.” [IPL96]

suggests that the SPARK subset is the most popular Ada subset. [Cha04] boasts that SPARK

programs are 100% statically free from: data flow errors, aliasing effects, side-effects, evaluation-

order effects, and all erroneous or implementation-defined behaviour. Also, given the almost zero

run-time library overhead, SPARK programs can be small enough to work in small, embedded, and

hard real-time systems [Cha04]. [Cha04] boasts both that SPARK has “met all the most stringent

software standards in the world” and that it “does represent best practice.”

It is easily possible to dedicate more than a few paragraphs to discussing the advantages of SPARK

for high integrity systems. However, the focus of this project is not to further explore the benefits of

using SPARK for high integrity systems. If a given organisation has already chosen SPARK as their

language then they will no doubt already be aware of its suitability. Readers wishing to know more

about SPARK are recommended to get a copy of [Bar03].

Instead, this project focuses on trying to determine if C++ is suitable, or can be made suitable for

use in high integrity safety critical systems.

Page 43: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

36

2.8 Software Safety Case Arguments

A number of the standards covered in Section 2.3 detailed that the selection of programming

language in the safety critical system should be justified and that a safety case should be produced.

Thus it is worth examining what a safety case is and what means could be used to argue justification

of the selection of programming language.

[HRM04] describes that the purpose of a safety case is to provide “a justification that a system or

equipment is safe to be used or deployed” in a given context. The safety case also contributes to risk

reduction [HRM04]. A safety case normally consists of two elements. Firstly a higher level

argument presents the principles on which the safety is base and identifies the safety requirements

[HRM04]. Secondly the safety case will provide supporting evidence for the higher level argument

[HRM04]. A software safety case is the element of a systems safety case that argues the safety of

the software component of the system. Importantly the software safety case should recognise that

the software does not exist in isolation to the remainder of the system and that the software’s

interaction with the hardware and other elements of the system are critical. [HRM04] makes an

important distinction that the safety case is the totality of the safety justification AND all of the

supporting material. Supporting material might include testing reports, validation reports, relevant

design information, etc [HRM04]. The safety case report is the document that presents all of the key

components of the safety case and reference all supporting documentation [HRM04].

There are numerous means of presenting a safety argument within a safety case. [HRM04]

describes safety arguments in Textual / Tabular forms, Traceability Matrices, Claim Structures,

Adelard’s Claims-Argument-Evidence notation, Bayesian Belief Networks and Goal Structuring

Notation (GSN). [HRM04] states that “GSN is one of the most expressive, well founded and tested

of these techniques” and thus GSN shall be used for this project.

2.8.1 Goal Structuring Notation (GSN)

[HRM04] describes the purpose of a goal structure is to show how goals (Figure 7) are broken

down into sub-goals, and eventually supported by evidence (solutions) (Figure 8) whilst making

clear the strategies (Figure 9) adopted, the rationale for the approach (assumptions, justifications)

(Figure 10) and the context (Figure 11) in which goals are stated. Goals, strategies and evidence are

linked using the ‘solved by’ connector (Figure 12) and assumptions, justifications and contexts are

linked to goals and strategies using the ‘in context of’ connector (also Figure 12)

Figure 7: GoalFigure 8: Evidence

Figure 9: Strategies

A/J

Figure 10: Assumptions /

Justifications

Figure 11: Context

Figure 12: Solved By / In Context Of

[HRM04] also identifies a six step process (Figure 13) to assist with developing a safety argument

using GSN. For full details and examples of the process refer to [HRM04].

Page 44: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

37

Figure 13: GSN Process Overview [HRM04]

[HRM04] also describes the concept of safety case patterns. The intention is to capture successful

argument approaches that can be re-used between the safety cases. In order to extend GSN to

represent generalised arguments a number of additional symbols are added (Figure 14).

Element to be instantiated. Option to be taken.

Structure to be developed.

n

Multiple (n) instantiations required.

Element to be instantiated and

developed.

0/1 instantiations required.

Figure 14: Key to GSN Extensions [HRM04]

2.8.2 GSN Software Safety Arguments

[CAS04] presents several patterns for arguing the safety of software within a safety critical system.

Patterns presented include arguments over product and process, hazards and requirements, and

functional vs non-functional properties. These arguments address both positive and negative aspects

of system behaviour [CAS04]. However, [CAS04] also identifies problems with these approaches.

The main problem stems from these arguments creating a discontinuity in the safety case [CAS04].

This is because the system argument has a product focus, and the software argument has a process

focus [CAS04]. In moving to a product oriented approach for software, [CAS04] goes on to develop

an evidence-base framework for software arguments. The main element of this argument relates to

demonstrating that the software contributions to system level hazards are either absent or are

handled [CAS04]. This is demonstrated by showing that all causes of hazardous software failure

mode are acceptable [CAS04]. [CAS04] identifies five categories of hazardous software failure

mode. These are:

• Omission: the value is never provided;

• Commission: a value is provided when it is not required (ie. a perfectly functioning service

would have done nothing);

• Early: the value is provided before the time (either real time, or relative to some other action)

at which it is required;

• Late: the value is provided after the time at which it is required; and

Page 45: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

38

• Value: the timing is correct, but the value delivered is incorrect.

The patterns described above do not directly address the justification of programming as part of the

safety argument. Thus there is a need to investigate how the language selection might be related

with such arguments.

2.9 Verification and Validation of Safety Critical Software

Section 2.2.2 briefly mentions that the availability and quality of support tools will impact upon the

language selection. This fact has inherently wider implications that may seem obvious and as such it

is worth dedicating this section to discussing support tools and their roles. Firstly though, a couple

of definitions.

Static analysis: is the analysis of source code before it is executed. Techniques include control flow

analysis, data flow analysis, symbolic execution, and checking the source code against a formal

mathematical specification. [Bar02] suggests that by using a combination of static analysis

techniques, a variety of properties can be guaranteed about a program. An example of a well-known

tool that performs such analysis is the SPARK Examiner (for Ada).

Dynamic testing: involves the execution of the source code against numerous test cases at various

levels of integration (ie. from the smallest routine, up to the system as a whole). Because software is

complex, it is impossible to be able to execute test cases for all possible inputs and outputs. Thus

techniques such as equivalence partitioning, boundary value analysis, and structural testing are

applied to give specified levels of dynamic test coverage. An example of a tool that support

dynamic testing and coverage analysis is Cantata++ (for C++).

[Bar02] states that a “key aspect in certification of a high integrity system is the ability to validate

the correctness of the system before it enters service.” Traditionally dynamic testing has been

extensively used following the initial development to gain confidence in the correct operation of the

system. However, [Bar02] points out that these techniques can be expensive for a number of

reasons. Firstly, dynamic testing tends to find faults late in the development lifecycle. Secondly, the

number of tests required to achieve the desired confidence and full code coverage within a

representation of the operational context can be unsurmountable.

Thus, there is motivation to use static analysis to verify software. In fact it is mandated by

[MoD97]. Static analysis has the advantage that if a program property is shown to hold, then it is

going to hold for all scenarios [Bar02]. This is often not the case for dynamic testing. In addition if

a language subset is used then there are likely to be static checkers required to ensure compliance

with the language subset.

Given the requirement for static checking, the programming language must support such a

mechanism [Bar02]. [Bar02] defines that the language should have properties that facilitate both

static and dynamic checking with tools within a reasonable time. Any rules (subsets) applied must

also be tool checkable to be practical. Also individual components should be amenable to analysis

so that checking may be performed at all levels of integration [Bar02], and without invalidating any

previous static analysis conducted. It is too late to benefit from static analysis if the program can

only be analysed once it is fully constructed [Bar02]. For a given system, and programming

language used to implement that system, it is important to highlight that showing the risks have

been reduced acceptably will involve a combination of both static and dynamic techniques.

Because of the heavy reliance on tools, be they compilers, static analysers, or dynamic testers,

thought must be given also to the verification and validation of the tools being used to verify and

validate the safety critical software. Each of the standards identified in Section 2.3 presents

Page 46: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

39

guidance on the use of tools within safety critical projects. This shall not be the focus of this project,

but it is important to be aware of when specific tools are discussed in relation to C++.

2.10 Summary of Literature Review

A broad range of literature relating to the project has been reviewed.

Section 2.1 has examined the C++ programming language, including its use and origins and

properties of the object-oriented paradigm. Comprehensive sources of C++ best practice, problems

and solutions have been identified.

Section 2.2 has examined programming languages in the context of safety critical software. A set of

criteria have been identified in Section 2.2.3 for assessing the safety of programming languages that

shall form part of the evaluation of this project. These criteria were selected because they were

deemed to be comprehensive.

Section 2.3 has examined programming languages in the context of the safety standards. Language

properties defined by the standards have been identified. A need has been identified for a means to

justify the selection of programming language for safety critical systems.

Section 2.4 has examined object-oriented technology in the context of safety critical systems. In

particular the Handbook for Object-Oriented Technology in Aviation [OOT04] has been identified.

Section 2.5 has examined C in the context of safety critical systems. The intention has been to

highlight issues that may also surface when looking at C++ in the context of safety critical systems.

Section 2.6 has examined C++ in the context of safety critical systems. Perceptions and opinions

relating to C++ and safety critical systems have been presented to provide background to the kinds

of issues that this project is likely to have to address. Importantly the High Integrity C++ (HICPP)

Coding Standard [PRG03] has been identified as an appropriate starting point for defining a safer

C++ subset.

Section 2.7 has examined alternatives to C++ for safety critical systems. Specifically Ada and

SPARK are examined. Importantly, this emphasises that this project does not intend to advocate

C++ as the most suitable software critical language, but instead to identify if C++ be used.

Section 2.8 has examined the purpose of the safety case and a means of clearly presenting the safety

arguments contained within the safety case. Specifically Goal Structuring Notation (GSN) has been

described. Patterns for software safety arguments have also been reviewed. An absence of a pattern

to justify the selection of programming language provides motivation for one to be developed as

part of this project. There is potential for this to be linked to the justification required by the

standards in Section 2.3.

Finally, Section 2.9 has examined some verification and validation issues relating to safety critical

software and the relationship this has to the tools used to support the programming language.

Page 47: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

40

3 Analysis of the C++ Language

Section 2 has identified numerous attributes of safer programming languages. Thus to consider if

C++ can be used in the safety critical context it is important to develop an understanding of some of

these criteria specifically in relation to the C++ programming language. Sections 3.1 to 3.3 examine

some of the fundamental aspects of these criteria, and then Section 3.4 moves to identify a means of

dealing with the issues identified.

3.1 Identification of C++ Behaviour Ambiguities

Section 2.2.2 details that unspecified, undefined, implementation-defined, and other definition

related behaviours should be identified, mitigated and controlled. This section focuses on

identifying those behaviours in C++.

Appendixes 8 to 14 present a list of all the identified unspecified, undefined, implementation-

defined and indeterminate behaviours of the C++ programming language. Table 5 (below) shows an

example of several unspecified behaviours. These behaviours were extracted directly (ie. directly

quoted) from [BSI03] and are referenced by both page number and chapter/section number. The

behaviours were identified through a series of keyword searches using words such as unspecified,

undefined, indeterminate, implementation and various lexically correct variations of these words.

It is fairly evident from the significant number of entries in these tables that there is a substantial

amount of such behaviour in the C++ programming language. These behaviours provide much

opportunity for safety related problems to arise in C++. Thus in order to be able to argue that there

is a safe way to employ the C++ language for safety critical applications, then these behaviours will

need to be controlled. This will be considered in Section 3.4.

Page Item / Description

48 3.7.3.1 Allocation Functions (para 2)

The order, contiguity, and initial value of storage allocated by successive calls to an allocation function is

unspecified.

65 5 Expressions (para 4) – Order of Evaluation

The order of evaluation of operands of individual operators and sub-expressions of individual expressions,

and the order in which side effects take place is unspecified. The precedence of operators is not directly

specified, but it can be derived from the syntax.

i = v[i++]; //the behaviour is unspecifiedi = 7, i++, i++; //i becomes 9

i = ++i + 1; //the behaviour is unspecifiedi = i + 1; // the value of i is incremented

72 5.2.8 Type Identification (para 1)

The result of a typeid expression is an lvalue of static type const std::type_info and dynamic type

const std::type_info or const name where name is an implementation-defined class derived from

std::type_info which preserves the behaviour described in 18.5.1. The lifetime of the object referred to by

lvalue extends to the end of the program. Whether or not the destructor is called for the type_info object at

the end of the program is unspecified.

75 5.2.9 Static Cast (para 7)

A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is

unchanged if the original value is within the range of enumeration values. Otherwise the resulting

enumeration value is unspecified.

Table 5: C++ Language Unspecified Behaviour (partial extract from Appendix 8)

Page 48: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

41

3.2 Identification of C++ Best Practice, Problems and Solutions

Simply being able to control the unspecified, undefined, indeterminate and implementation-defined

behaviours of C++ is insufficient to make the language safer in the context of safety critical

systems. The correct employment of the language is also critical to ensuring safety.

Section 2.1.5 details a number of published C++ texts that identify numerous cases of best practice,

problems and solutions. This advice is broad in its coverage and considers issues from individual

language constructs that are prone to misunderstanding or misuse through to higher level design

issues and programmer skills. Each of the individual items/rules/guidelines presented by these texts

have been directly extracted and are summarised in Appendixes 1 to 6. Table 6 (below) shows an

example of the Industrial Strength C++ items. In total these appendixes cover 438

items/rules/guidelines relating to the production of C++ code. While there are certainly other texts

that also present items/rules/guidelines on the production of C++ code, it is beyond reasonable

expectation for this project to be able to cover all of them. The texts that have been selected are

widely acknowledged in the C++ community and for that reason are assumed to represent quality

advice on the production of C++ code. There is also substantial overlap between the advice

provided by these texts. Thus one may conclude that for the most part the coverage of these texts of

C++ best practice, problems and solutions is substantial. There is still the possibility that problems

are not identified here, but these shall be addressed in Section 5.1.1.

Industrial Strength C++ Item

Rule 8.1 Delete should only be used with new.

Rule 8.2 Delete[] should only be used with new[].

Rule 8.3 Do not access a pointer or reference to a deleted object.

Rec 8.4 Do not delete this.

Rec 8.5 If you overloaded operator new for a class, you should have overloaded operator delete.

Rec 8.6 Customise the memory management for a class if memory management is an unacceptably large part

of the allocation and deallocation of free store objects of that class.

Rec 9.1 Objects with static storage duration should be declared only within the scope of a class, function, or

anonymous namespace.

Rec 9.2 Document how static objects are initialised.

Rule 10.1 Declare data members private.

Rec 10.2 If a member function returns a pointer or reference, you should document how it should be used and

how long it is valid.

Rec 10.3 Selection statements (if-else and switch) should be used when the control flow depends on an object’s

value; dynamic binding should be used when the control flow depends on the object’s type.

Rule 10.4 A public base class must have either a public virtual destructor or a protected destructor.

Rule 10.5 If you derive from more than one base class with the same parent, that parent should be a virtual base

class.

Rec 10.6 Specify classes using preconditions, postconditions, exceptions, and class invariants.

Rec 10.7 Use C++ to describe preconditions, postconditions, exceptions and class invariants.

Rec 10.8 It should be possible to use a pointer or reference to an object of a derived class whenever a pointer or

reference to public base class object is used.

Rec 10.9 Document the interface of template parameters.

Table 6: Industrial Strength C++ Items (partial extract from Appendix 1)

3.3 Identification of OOTiA Recommendations

Although C++ is technically a multi-paradigm language, it is in its object-oriented form that this

project has focussed. Section 2.4.1 detailed a number of concerns relating to the use of object-

oriented technology in safety critical applications. Section 2.4.2 identifies that [OOT04] provides

advice on mitigating such problems with the paradigm. Each of the rules and guidelines presented

by [OOT04] has been directly extracted and summarised in Appendix 7. Table 7 (below) shows an

example of several OOTiA guidelines. [OOT04] also presents a number of recommendations

relating to achieving DO-178B compliance for software utilising object-oriented technology. These

Page 49: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

42

(sections 3.10 – 3.12 in Volume 3 of [OOT04]) haven’t been covered in this section because they

are beyond the scope of safe language criteria.

OOTiA Guideline

3.3 Single Inheritance and Dynamic Dispatch

3.3.4 Inheritance with Overriding

Simple overriding rule: An operation may redefine an inherited operation, and a method may implement an operation

so long as changes to its signature guarantee substitutability.

Accidental override rule: To ensure that overriding is always intentional rather than accidental, design and code

inspections should consider whether locally defined features are intended to override inherited features with a

matching signature.

Simple dispatch rule: When an operation is invoked on an object, a method associated with the operation in its run

time class should be executed. This rule applies to all calls except explicit calls to superclass methods, which should

be addressed as described by the Method Extension guidelines.

Complete initialisation rule: Each attribute must be initialised to a value consistent with the class invariant by the

class.

Initialisation dispatch rule: No overridden method should be called during the initialisation (construction) of an

object.

Dispatch time rule: All dispatch times should be bounded and deterministic.

Object code traceability rule: Everywhere concerns about source code to object code traceability and timing analysis

dictate, the compiler vendor may be asked to provide evidence of deterministic, bounded mapping of the dispatched

call. If the evidence is not available from the compiler vendor, it may be necessary to examine the structure of the

compiler-generated code and data structures (e.g. method tables) at the point of call.

Table 7: OOTiA Guidelines (partial extract from Appendix 7)

3.4 Summary and Direction

Even a brief inspection of many of the items identified in Section 3.1 to 3.3 reveals many problems

and pitfalls from which it is possible to conclude that the unrestricted use of the C++ language is

not suitable for high integrity and safety critical applications. However this prognosis does not

discount the possibility that these issues may be able to be controlled. A subset of the language may

provide the restrictions necessary to make C++ safer. Section 2.6.4 identified the High Integrity

C++ (HICPP) Coding Standard Manual [PRG03] as defining a set of rules and guidelines for the

production of C++ code that is portable, readable, clear and unambiguous. Specifically in order to

avoid problems with C++ and thus reduce the incidence of errors, the requirements detailed by

[PRG03] express:

• Restrictions on the use of the language constructs or library functions that are not completely

defined by the ISO C++ Standard – ie. the unspecified, undefined and indeterminate

behaviours identified in Section 3.1.

• Restrictions on language constructs that permit varied compiler interpretation – ie. the

unspecified and implementation-defined behaviours identified in Section 3.1.

• Restrictions on language constructs or library functions that are known to be frequently

misunderstood or misused by programmers thereby leading to errors – ie. the best practice,

problems and solutions identified in Section 3.2 and the guidelines relating to object oriented

technology identified in Section 3.3.

HICPP seems to address the issues identified in Sections 3.1 to 3.3. However the number of issues

presented is large and a number of them are complex. Thus there is no assurance that HICPP’s

coverage is complete and there is a need to conduct a full check. Section 4.1 will fully consider the

HICPP coding standard in relation to the issues and items/rules/guidelines identified in Sections 3.1

to 3.3.

Page 50: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

43

4 Development and Enforcement of a Safer C++ Subset

Section 3.4 states that the number of issues presented is large and a number of them are complex.

Thus there is no assurance that the High Integrity C++ (HICPP) Coding Standard’s coverage is

complete and there is a need to conduct a full check. Section 4.1 considers the HICPP coding

standard in relation to the issues and items/rules/guidelines identified in Sections 3.1 to 3.3. Where

relevant, deficiencies in the HICPP rules and guidelines have been identified. In Section 4.2 a set of

additional rules and guidelines has then been developed to address the identified deficiencies.

Section 4.3 identifies and reasons about those rules that were not referenced in Sections 4.1 and 4.2.

With a complete set of rules and guidelines now fully defined, Section 4.4 examines how these rules

and guidelines can be enforced.

4.1 Assessment of the High Integrity C++ Coding Standard

In Section 3 a set of issues and behaviours was established against which to assess HICPP. They

included C++ behaviours, best practice C++, and the OOTiA recommendations. This section

describes the assessment of HICPP. The results are presented in the column labelled ‘Control’ of

the tables shown in Appendixes 1 – 14. An example of these results for a small set of the Industrial

Strength C++ items is shown in Table 8.

Industrial Strength C++ Item Control

Rule 8.1 Delete should only be used with new. Rule 12.3 (direct)

Rule 8.2 Delete[] should only be used with new[]. Rule 12.3 (direct)

Rule 8.3 Do not access a pointer or reference to a deleted object. Rule 12.8 (avoids)

Rec 8.4 Do not delete this. New Rule (4)

Rec 8.5 If you overloaded operator new for a class, you should have overloaded

operator delete.

Rule 12.6 (direct)

Rec 8.6 Customise the memory management for a class if memory management is

an unacceptably large part of the allocation and deallocation of free store

objects of that class.

Efficiency

Rec 9.1 Objects with static storage duration should be declared only within the

scope of a class, function, or anonymous namespace.

Rule 8.1.1 (direct)

Rule 8.1.2 (direct)

Rule 8.2.2 (direct)

Guideline 6.6 (supports)

Rec 9.2 Document how static objects are initialised. Rule 8.2.2 (direct)

Guideline 8.3.2 (avoids)

Maintenance

Rule 10.1 Declare data members private. Rule 3.4.1 (direct)

Rec 10.2 If a member function returns a pointer or reference, you should document

how it should be used and how long it is valid.

Maintenance

Rec 10.3 Selection statements (if-else and switch) should be used when the control

flow depends on an object’s value; dynamic binding should be used when

the control flow depends on the object’s type.

Software Engineering –

Object Oriented Design

Rule 10.4 A public base class must have either a public virtual destructor or a

protected destructor.

Rule 3.3.2 (direct)

Guideline 17.7 (direct)

Rule 10.5 If you derive from more than one base class with the same parent, that

parent should be a virtual base class.

Rule 3.3.15 (direct)

Rec 10.6 Specify classes using preconditions, postconditions, exceptions, and class

invariants.

Software Engineering –

Object Oriented Design

Rec 10.7 Use C++ to describe preconditions, postconditions, exceptions and class

invariants.

Software Engineering –

Object Oriented Design

Rec 10.8 It should be possible to use a pointer or reference to an object of a derived

class whenever a pointer or reference to public base class object is used.

Rule 3.3.3 (direct)

ISO C++ defines

Rec 10.9 Document the interface of template parameters. Maintenance

Table 8: HICPP Coverage of Industrial Strength C++ Items (partial extract from Appendix 1)

Page 51: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

44

Where a rule or guideline was determined to be applicable in mitigating or avoiding a given

problem then that rule or guideline reference would be annotated in the ‘Control’ column. In some

cases it was possible to obtain a direct mapping between an item/rule/guideline from the literature

and the rule or guideline in HICPP. In other cases a combination of rules were required to work

together to collectively avoid and/or mitigate the item/rule/guideline from the literature. Each of the

rule or guideline entries in the ‘Control’ column are bracket annotated with the keyword ‘direct’,

‘avoids’ or ‘supports’. The ‘direct’ annotation means that the rule or guideline applies directly to

mitigating the problem. The ‘avoids’ annotation means that the existence of the rule or guideline

creates a scenario through which the problem will generally be avoided. The ‘supports’ annotation

means that the rule or guideline applies in a generally supporting manner for mitigating or avoiding

the problem.

In cases where the rules or guidelines could not be applied to fully mitigate or avoid the problem,

the residual problem could be mitigated or avoided through the application of a number of general

design principles or other means. In such cases a number of category labels were used and they are

presented in the list below. As the evaluation was carried out it became clear that a number of the

issues presented were non-specific to the language, a higher-level software engineering issue, or

related to the quality of the programmers. It is mostly difficult and nearly impossible to define rules

to cover these items, as they are specific to the type of problem being solved. Thus it is not possible

to fully detach the language selection from the system’s context. This is a very important outcome

and will be examined further in Sections 5.1.

• Software Engineering – Requirements: The correct and unambiguous specification of

requirements works to mitigate or avoid the scenario. If the requirements are poorly specified

it may be difficult to avoid problems.

• Software Engineering – Analysis: An appropriate level of analysis of the problem and

solution works to mitigate or avoid the scenario. The software should be designed to ensure

that it is compatible with static analysis.

• Software Engineering – Design: The development of a ‘good’ design works to mitigate or

avoid the scenario. For example, attempting to solve a problem in a way that works against

the paradigm or intent of the language constructs may lead to a ‘poor’ design.

• Software Engineering – Object Oriented Design: The development of a ‘good’ object oriented

design works to mitigate or avoid the scenario. This includes the numerous object oriented

design rules and guidelines presented in [PRG03], but also encompasses fundamental design

issues relating to the context of the problem being solved. In particular the development of an

appropriate class hierarchy, appropriate use of abstraction and inheritance and application of

software engineering methods is critical to achieving a good object oriented design.

• Software Engineering – Exception Design: The development of appropriate exception class

hierarchy and exception class mechanics works to mitigate or avoid the scenario.

• Software Engineering – Verification: These items are related to the verification of the

software. They should be considered during the design such that the software is designed to

be tested, but are not considered to present language specific safety issues.

• Maintenance: These items relate to producing software that is maintainable. This does not

only relate to the ease of finding and understanding sections of the code, but also to ensuring

that there is minimum likelihood of the maintainers introducing errors during maintenance

activities.

Page 52: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

45

• Programmer Skill: The employment of programmers with good C++ skills as well as a good

knowledge of software in the safety domain works to mitigate or avoid these problems.

Furthermore a broad understanding of likely language and design related problems is also

essential.

• Programmer Attitude: The employment of C++ programmers, regardless of their level of

skill, with inappropriate attitudes towards software in the safety domain is likely to negatively

impact upon the overall safety of the system. Programmers with the correct attitude will

mitigate these problems. Thus programmers should be recruited that have an awareness of

software safety issues, are familiar with common problems within the C++ language, are

aware of the impact of the unrestricted use of the language and are willing to promote a safe

design at all levels.

• ISO C++ defines: The item is clarified by the C++ standard and relates to a problem that

arose due to varied compiler implementations or interpretation prior to the release of the

official standard. Presuming that a fully ISO compliant compiler is used these issues will not

present any problems. Availability of ISO compilers is considered in Section 6.1.1 and

6.2.3.1.

Finally where neither the rules, guidelines or categories presented above were considered sufficient

to mitigate or avoid the problem then a new rule or guideline annotation was made (eg. Rule 1 or

Guideline 2). New rules use an integer for labelling, whereas the rules and guidelines from HICPP

use a decimal labelling system.

An inspection of the results of the activity reveals that the HICPP’s overall coverage of the issues

has been quite comprehensive. However there was a significant proportion whereby no reference to

a HICPP rule was possible and one of the pre-defined category labels was used. This means that

producing a safe design in C++ is more than just enforcing a subset. It also means that the design

must be matched to the intent of the language constructs and the language must suit the domain and

application. This means it may be difficult to detach the language selection from the design

(functional properties of the system).

There have been a number of areas identified whereby further rules or guidelines are required.

These areas relate to both the base language and the standard template library (STL). The new rules

and guidelines are described in Section 4.2.

4.2 Development of Additional Rules

From the work described in Section 4.1, numerous deficiencies were identified that are best

addressed through the addition of new rules or guidelines to [PRG03]. The following sections

describe the rules and guidelines. They have been grouped under similar headings to the rules and

guidelines presented in [PRG03] to allow them to be correlated to [PRG03].

4.2.1 General (HICPP 3.1)

Rule 1 – Always return stream references from operator << and operator >>.

Justification: operator << and operator >> should return a reference to the stream in order to permit

chaining.

Reference: [Sut00] Item 20

Page 53: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

46

4.2.2 Constructors and Destructors (HICPP 3.2)

Rule 2 – Do not use or pass this in constructor initialiser lists.

Justification: Until the constructor has completed, the object pointed to by this is not fully

constructed. Calling a member function in a member initialisation list can result in the member

function trying to access uninitialised members of the class.

Exception: Use the this pointer to access the value or any subobjects during the construction of a

const object. Other means of accessing the value of the object can result in unspecified behaviour.

Reference: [Hen97] Rec 5.7, [BSI03] 12.6.2 , [BSI03] 12

Rule 3 – Do not assume constructor arguments will or will not be evaluated prior to the

allocation of the object occurring.

Justification: It is unspecified whether the allocation function is called before or after evaluating the

constructor arguments, but before entering the constructor. It is also unspecified whether the

arguments to a constructor are evaluated if the allocation function returns the null pointer or exits

using an exception.

Reference: [BSI03] 5.3.4

4.2.3 Object Oriented Design (HICPP 3.4)

Rule 4 – Do not delete this.

Justification: It is rarely correct for an object to commit suicide and can be an indication of poor

object oriented design. Allowing functions to delete this can lead to undefined behaviour if the

object is subsequently accessed when returning from the function.

Reference: [Hen 97] Rec 8.4

Rule 5 – Avoid using type identification information.

Justification: The header <typeinfo> defines a type associated with type information generated by

the implementation. Thus a program using such features may not be portable. The presence of type-

based control structures in a program can be an indication of a poor object-oriented design.

Implement type-based decisions with dynamic binding and not with type-based conditional control

structures.

Reference: [BSI03] 5.2.8

4.2.4 Complexity (HICPP 4)

Rule 6 – Avoid recursion.

Justification: Recursion makes code difficult to understand and analyse. It also makes the

determination of resource usage difficult. Also, if control re-enters a declaration recursively while

the object is being initialised, the behaviour is undefined.

Reference: [BSI03] 6.7

Page 54: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

47

4.2.5 Control Flow (HICPP 5)

Rule 7 – Do not perform equality comparisons on pointers to virtual functions.

Justification: Do not make equality comparisons of pointers to virtual functions as this can result in

unspecified behaviour.

Reference: [BSI03] 5.10

4.2.6 Declarations and Definitions (HICPP 8)

Rule 8 – Do not self-initialise variables.

Justification: Initialising a variable in terms of itself is likely to lead to undefined behaviour.

int var = 12;{

double var = var; // undefined behaviour!// ...

Reference: [Dew03] Gotcha #21

Rule 9 – Constants declared in pure abstract classes should not involve run-time computation.

Justification: Constants whose values are computed at run-time require the generation of code to

perform the computation and assignment. This conflicts with the definition of an interface which is

not permitted to have code or data.

Reference: [OOT04] 3.4.4

Rule 10 – Do not attempt to create a null reference.

Justification: Attempting to create a null reference by binding it to the object obtained by de-

referencing a null pointer causes undefined behaviour and thus should not be attempted.

Reference: [BSI03] 8.3.2

4.2.7 Exceptions (HICPP 9)

Rule 11 – Constructors of types thrown as exceptions should not themselves throw exceptions.

Justification: If such a constructor throws an exception, then the original exception is lost and

forgotten and there is thus no way of dealing with the original problem. For copy constructors, the

exception object is copied to an area of memory managed by the exception handling system before

leaving the scope in which the throw is done. Terminate() is called if the copy fails.

Reference: [Hen97] Rec 12.6, [BSI03] 15.5.1

Rule 12 - If a function isn’t going to handle (or translate or deliberately absorb) an exception,

it should allow the exception to propagate up to a caller that can handle it.

Justification: In a template, if exceptions are thrown they should be propagated seemlessly through

to the caller because the caller is in a better position to know the context of the exception.

Reference: [Sut00] Item 8

Page 55: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

48

Rule 13 – Do not rely on the lifetime of temporary exception objects.

Justification: The memory held by the temporary object can be deallocated by the implementation

any time after the last handler being executed for the exception exists, by any means other than

throw.

Reference: [BSI03] 15.1

Rule 14 – Never refer to any non-static member or base class of an object in an exception

handler for a function try block of a constructor or destructor for that object.

Justification: Referring to any non-static member or base class of an object in an exception handler

for a function try block of a constructor or destructor for that object results in undefined behaviour.

Reference: [BSI03] 15.3

4.2.8 Memory Management (HICPP 12)

Guideline 15 – Use stack objects instead of heap based objects where possible.

Justification: Whenever possible, objects should be created on the stack instead of with new. Stack

objects are less expensive to create and the risk of a memory leak occurring is substantially less,

especially if exception safe classes are used. Objects should be created with new only if the lifetime

is to be controlled outside the function creating the object. Objects should not be created with new

merely for the convenience of gaining access to a pointer to the object. Each heap based object must

always be accessible through either a static pointer or an object on the stack that owns the object.

Reference: [Hen97] Rec 12.9

Guideline 16 – Be prepared for out of memory conditions.

Justification: When operator new can’t allocate the requested memory, an exception is thrown. To

ensure the out of memory condition is handled in a controlled manner, then the program should be

prepared to handle memory allocation failures.

Reference: [Mey98] Item 7

Rule 17 – Do not make a request for the allocation of a zero or negatively sized object.

Justification: The effect of the allocation for negatively sized object has undefined behaviour. De-

referencing a pointer returned from a request for a zero sized object is also undefined.

Reference: [BSI03] 3.7.3.1, 5.3.4

4.2.9 Portability (HICPP 13)

Guideline 18 – Avoid linking to languages other than C++ or C.

Justification: The characteristics of linkage to other languages has undefined and implementation

defined characteristics associated with it and should thus be avoided. Section 1.6 in [PRG03] also

states “the embedding of code, written in languages other than C++, within C++ code is forbidden

unless accompanied by a written justification for its use.”

Reference: [BSI03] 5.2.2

Page 56: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

49

4.2.10 Pre-Processor (HICPP 14)

Rule 19 – Do not use the pre-processor # operator and ## operator.

Justification: If the replacement that results from such operations is not a valid character string or

pre-processing token then the behaviour is undefined.

Reference: [BSI03] 16.3.2, 16.3.3

Rule 20 – Ensure that the digit sequence for the # line pre-processing directive is > 0 and

< 32768.

Justification: If the digit sequence specifies a number outside this range then the behaviour is

undefined.

Reference: [BSI03] 16.4

4.2.11 Standard Template Library (HICPP 17)

Guideline 21 - Choose carefully among erasing options.

Justification: The correct choice of erase option depends on how the objects to erase are identified,

the type of container the objects are stored in, and what else is to be done while erasing the objects.

[Mey01] recommends the following:

• To eliminate all objects in a container that have a particular value: if the container is a vector,

string or deque, use the erase remove idiom; if the container is a list, use list::remove; if the

container is a standard associative container, use its erase member function.

• To eliminate all objects in a container that satisfy a particular predicate: if the container is a

vector, string, or deque, use the erase-remove_if idiom; if the container is a list, use

list::remove_if; if the container is a standard associative container, use remove_copy_if and

swap, or write a loop to walk the container elements, being sure to postincrement the iterator

when it is passed to erase.

• To do something inside the loop (in addition to erasing objects): if the container is a standard

sequence container, write a loop to walk the container elements, being sure to update the

iterator with erase’s return value each time it is called; if the container is a standard

associative container, write a loop to walk the container elements, being sure to post-

increment the iterator when it is passed to erase.

Reference: [Mey01] Item 9

Guideline 22 – Ensure allocator conventions and restrictions are conformed to.

Justification: [Mey01] provides the following guidance for writing a custom allocator:

• Make the allocator a template, with the template parameter T representing the type of objects

for which memory is being allocated.

• Provide the typedefs pointer and reference, but always have pointer be T* and reference be T&.

• Never give allocators per-object state. In general, allocators should have no non-static

members.

Page 57: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

50

• Remember that an allocator’s allocate member functions are passed the number of objects for

which memory is required, not the number of bytes needed. Also remember that these

functions return T* pointers (via the pointer typedef), even though no T objects have yet been

constructed.

• Be sure to provide the nested rebind template on which standard containers depend.

• All allocators of the same type must be equivalent.

Reference: [Mey01] Item 10, 11

Guideline 23 - Specify comparison types for associative containers of pointers and iterators.

Justification: Standard associative containers of pointers will be sorted by the values of the pointers.

If this is undesirable then create a ‘functor’ class to serve as a comparison type.

Reference: [Mey01] Item 20

Rule 24 - Make sure destination ranges are big enough.

Justification: Whenever an algorithm requiring the specification of a destination range is used,

ensure that the destination range is big enough already or is increased in size as the algorithm runs.

To increase the size as you go, use insert iterators, such as ostream_iterators or those returned by

back_inserter, front_inserter, or inserter.

Reference: [Mey01] Item 30

Rule 25 - Avoid remove-like algorithms on containers of pointers.

Justification: Standard remove-like algorithms can result in memory leaks when used on containers

of pointers. Instead manually implement such activities by reference counting smart pointers,

manual deletion and nullification of pointer prior to invoking remove-like algorithm.

Reference: [Mey01] Item 33

Rule 26 – Never dereference an invalid iterator.

Justification: When using iterators, there are a number of issues to be aware of.

1. Valid values: Is the iterator dereferenceable? For example, writing *e.end() is a programming

error.

2. Valid lifetimes: Is the iterator still valid since last being used? Has it been invalidated by

some operation since it was obtained?

3. Valid ranges: Is the pair of iterators a valid range? Is first really before (or equal to) last? Do

both point into the same container?

4. Illegal builtin manipulation: Is the code trying to modify a temporary of builtin type? For

example, --e.end().

Reference: [Sut00] Item 1, [BSI03] 24.5.3

Page 58: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

51

Rule 27 – Always check and ensure compliance with the pre-conditions for STL functions.

Justification: The behaviour of STL functions is only guaranteed if the function arguments and state

meet the defined pre-conditions for the function. If an argument to a function has an invalid range

or the pre-conditions are not met in any other way then the behaviour is undefined.

Reference: [BSI03] 17.4.3.2, 17.4.3.7, 21.3.4, 23.2.2.4, 26.3.2.1, 26.3.2.2, 26.3.2.3, 26.3.2.6,

26.3.2.7, 26.3.3.1, 26.3.3.2, 26.3.6, 26.3.9.2, 26.3.9.3, 27.4.3.2, 27.4.4.1, 27.7.1.3, 27.8.1.1,

27.8.1.4,

Rule 28 – Only use the macro offsetof in <cstddef> with non-static POD types.

Justification: The macro offsetof in <cstddef> only accepts types of POD structure and POD

union. The result of applying the offsetof macro to a field that is a static data member or a function

member is undefined.

Reference: [BSI03] 18.1

Rule 29 – Do not use iterators to hold singular values.

Justification: The results of most expressions that involve singular values in iterators is undefined.

Reference: [BSI03] 24.1

Rule 30 – Operations on types used with the complex and valarray classes shall not throw

exceptions.

Justification: If any operation on type T throws an exception the effects are undefined.

Reference: [BSI03] 26.1

Rule 31 – No user defined function should call the imbue function.

Justification: If any user function calls imbue, the behaviour is undefined.

Reference: [BSI03] 27.1.1

Rule 32 – Avoid using operator[] to access STL containers, use iterators instead.

Justification: Operator[] does not include bounds checking.

Reference: [BSI03] 17.4.3.7, 21.3.4.

4.3 Rules and Guidelines Not Referenced in the Assessment

There are a number of HICPP rules and guidelines that were not referenced in the assessment

described by Section 4.1. This raises the obvious question: why is the rule or guideline is present in

HICPP if it is not used to enforce a C++ behaviour or best practice? To answer this question, each

of these rules or guidelines is listed below with the reasoning for its inclusion in HICPP despite

being absent from the references in this assessment. In most cases these rules and guidelines

improve readability and maintainability.

Page 59: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

52

Rule 2.1 – Thoroughly document in the code any deviation from a standard rule.

Reasoning: This rule is required for the management and documentation of code produced with the

subset.

Guideline 3.1.12 – Provide an output operator (‘operator<<’) for ostream for all classes.

Reasoning: This rule is useful for debugging and testing of code.

Rule 3.3.16 – Explicitly declare polymorphic member functions virtual in a derived class.

Reasoning: This rule improves class documentation.

Rule 5.3 – Avoid conditional expressions that always have the same result.

Reasoning: This rule relates to good programming and design practice and does not explicitly

address individual language issues.

Rule 10.5 – Always discard the result of an assignment operator.

Reasoning: This rule relates to avoiding the possibility of mistaking the assignment operation with a

comparison operation. This is due to the lexical similarity between ‘=’ and ‘==’. This rule works to

avoid programmer errors of misplacement, omission and addition.

Rule 10.10 – Avoid statements that have no side effects.

Reasoning: This rule improves code readability and maintainability.

Rule 10.16 – Do not use the increment operator (‘++’) on a variable of type ‘bool’.

Reasoning: This is deprecated in the ISO C++ standard and the rule is possibly redundant given that

HICPP subsets the ISO C++ standard.

Rule 10.19 – Do not use the comma operator.

Reasoning: This rule improves code readability and maintainability.

Rule 11.1 – All functions that have the same name should have similar behaviour, varying

only in the number and/or types of parameters.

Reasoning: This rule improves code readability and maintainability.

Guideline 14.2 – Do not use tab characters in source files.

Reasoning: This rule improves readability and maintainability across different editing

environments.

Guideline 14.3 – Write pre-processor directives to begin in column 1 with no whitespace

between the ‘#’ and the pre-processor directive.

Reasoning: This rule improves readability and maintainability.

Page 60: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

53

Guideline 14.4 – Write pre-processor directives to begin in column 1 with whitespace between

the ‘#’ and the pre-processor directive representing nesting in pre-processor conditionals.

Reasoning: This rule improves readability and maintainability.

Rule 14.18 – Do not use digraphs or trigraphs.

Reasoning: This rule works to prevent mis-translation and confusion between potentially similar

sets of character strings.

Rule 15.3 – Do not rely on the value of an enumerator.

Reasoning: This rule improves readability and maintainability.

4.4 Enforcement of C++ Rules and Guidelines

Having deduced that the HICPP coding standard plus the additional rules and guidelines defined in

Section 4.2 has been deemed sufficient to promote the development of high integrity C++ code, it is

then necessary to examine how well these rules and guidelines lend themselves to enforcement, and

in particular auto-enforcement. Auto-enforcement is necessary if C++ is to be used in other than

trivial high integrity software development. This is because it is impractical for the large number of

rules and guidelines to be manually enforced.

A number of tools have been assessed with respect to their auto-enforcement capabilities of the

rules and guidelines (both HICPP and additional rules and guidelines defined in Section 4.2). Note

that the focus has been on being able to enforce the rules and guidelines statically (ie. at or before

compile time). Static enforcement was identified as being necessary in Section 2.9. The results of

the assessment are presented in the last column (labelled ‘Enforced’) of the tables shown in

Appendixes 1 – 14. An example of these results for a small set of the Industrial Strength C++ items

is shown in Table 9 (Section 4.4.5). Note that the item/rule/guideline from the literature (columns 1

and/or 2 of these tables) against which one or more particular rules or guidelines from HICPP was

annotated (labelled ‘Control’) was used to provide a contextual basis for considering if the tools can

provide auto-enforcement of the rule or guideline. Thus aspects of any given rule or guideline

(‘Control’) that didn’t work to mitigate or avoid the particular item/rule/guideline from the literature

(columns 1 and/or 2) were not considered for that annotated instance of the rule or guideline.

A number of widely used C++ analysis tools have been identified for this evaluation. The

assessment was limited to these tools for enforcing the set of rules and guidelines and for

contributing to the static analysis and dynamic testing requirements.

4.4.1 QA C++

The Programming Research Group (PRG) has developed the QA C++ tool for auto-enforcing the

HICPP coding standard and for analysing source code (deep flow static analyser). Version 2.0 of

the tool used throughout this assessment provides over 800 warning and error messages. QA C++

analyses source code to identify dangerous usage of the C++ language. Source code is identified

which is non-portable, difficult to maintain, overly complex, or written in any way that is likely to

cause problems [PRG04]. The tool will also identify language usage which is not compliant with

the ISO C++ standard or which is classified as giving rise to unspecified, undefined or

implementation-defined behaviour. In addition [PRG04] describes QA C++ to also provides the

following features:

• 8 function-based, 10 file-based, and 8 class-based code metrics which provide a quantifiable

measure of numerous code attributes;

Page 61: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

54

• function structure diagrams to provide an insight into control flow, relationship diagrams to

demonstrate function calling, global referencing, include file trees, class hierarchies, and class

implementation details;

• demographic analysis to provide an overall assessment of code quality against industry

benchmarks; and

• cross-module analysis capability, delivering memory allocation mismatches, function

recursion, and other global issues.

4.4.2 PC-Lint / FlexeLint

Gimpel Software has developed the PC-Lint / FlexeLint diagnostic tool for C and C++. The tool

currently provides a substantial number of checks relating to both C and C++ in release version

8.00. PC-Lint / FlexeLint detection capabilities include expression analysis, order of evaluation

problems, loss of precision, signed/unsigned mismatches, unusual constants, suspicious

comparisons, unusual indentation, suspicious truncation, unintended name hiding, suspicious

initialisation, inappropriate use of pointers to auto variables and macro irregularities [Gim01]. PC-

Lint / FlexeLint provides stricter type-checking than the C++ base language [Gim01]. A recent

addition to PC-Lint / FlexeLint is its value tracking features.

4.4.3 MALPAS

MALPAS is not explicitly a C++ tool. MALPAS is a rigorous verification tool that will reveal

program structure, examine functionality in detail, and check conformance with the specification

[ATC03]. MALPAS has been used to improve system integrity, demonstrate to regulatory bodies

and customers that programs are error free, and to produce safety critical software more cost

effectively [ATC03].

[ATC03] describes that MALPAS applies the following analysis techniques:

• Control Flow Analysis – identifies unstructured control flow in a program;

• Data Use Analysis – identifies all the inputs and outputs of each procedure to reveal data

handling errors;

• Information Flow Analysis – each procedure is analysed to deduce the information on which

its outputs depend;

• Path Assessor – all possible paths through the program are analysed and the number of paths

through the code is reported for each procedure;

• Semantic Analysis – re-expresses the complete semantics of the procedure in a formal

mathematical notation to check for discrepancies between the program’s behaviour and its

specification; and

• Compliance Analysis – supports a formal proof that a procedure’s preconditions, and

postconditions hold and behave in accordance with the specification.

MALPAS works by firstly translating the source code into the MALPAS Intermediate Language

(IL). The MALPAS analysis is then conducted on the program expressed in the MALPAS IL. Thus

MALPAS can conceivably be applied to programs of any programming language. There is

presently no automatic translation available for C++ into the MALPAS IL, but it is believed that it

would be possible to develop such a translator. There are generic object-oriented mappings

Page 62: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

55

available for the MALPAS IL that permit the manual translation of C++ into the MALPAS IL.

Manual translation of C++ into the MALPAS IL may be time consuming for a project of other than

trivial size.

4.4.4 Cantata++

Cantata++ provides facilities for dynamic testing, coverage analysis, and static analysis [IPL98].

[IPL98] states that the benefits of Cantata++’s approach to testing are improved productivity,

documentation, repeatability, maintainability and quality.

Cantata++’s dynamic testing facilities can be used to execute the software under test in order to

verify its compliance with requirements [IPL98]. These tests can be carried out at unit, integration

and system level. The dynamic testing features of Cantata++ include the test harness, checking

values and data, exception and template testing, simulating external software, timing analysis, and

test re-use. Cantata++ is capable of handling test cases generated using both functional (black-box)

or structural (white-box) techniques [IPL98]. Cantata++ is capable of checking for both expected

behaviour (positive testing) and unexpected behaviour (negative testing).

Cantata++’s coverage analysis can be used to measure the proportion of software exercised by the

aforementioned dynamic testing. The metrics may be viewed both as non object-oriented coverage

measures, or using Cantata++’s object-oriented coverage reporting facilities [IPL98]. Cantata++

supports statement coverage, decision (or branch) coverage, boolean expression coverage, call pair

(call/return) coverage, call coverage, and modified condition / decision coverage (MC/DC).

Cantata++’s static analysis facilities are limited to the gathering and reporting of metrics on the

code [IPL98]. This relates to the enforcement of coding standards, measurement of code complexity

and structure, and object-oriented metrics assessment.

4.4.5 Evaluation of Rules

Given that QA C++ has been specifically developed for enforcing HICPP, then it shall be the first

tool considered. Note that PC-Lint / FlexeLint has only been considered where QA C++ has been

assessed to not provide a complete detection and enforcement capability. Thus there may be a

significant proportion of rules and guidelines that may be detected by PC-Lint / FlexeLint that

won’t be identified. Time constraints on the project meant that a limit had to be placed on the scope

of the assessment. Section 7.2 shall identify this as an area worth considering for further work.

Where QA C++ was determined to be applicable in enforcing the rules and guidelines applicable to

a particular item then ‘QAC++’ would be annotated in the ‘Enforced’ column (Table 9). In some

cases it was possible to obtain a direct mapping between the rules and the tool’s enforcement

capabilities. However there were other cases where QA C++ was only assessed to provide a partial

enforcement of particular rules or guidelines. In this case the annotation ‘QAC++ partial’ was used.

Where QA C++ was assessed to provide insufficient enforcement then PC-Lint / FlexeLint was

assessed to determine if it could be used to supplement the rule and guideline enforcement. The

annotations ‘PC-Lint’ and ‘PC-Lint partial’ have been used to indicate full or partial PC-Lint

coverage of the rules and guidelines respectively. Note that in some cases a rule or guideline would

be annotated with both ‘QAC++ partial’ and ‘PC-Lint partial’. In none of the cases examined did

this then equate to a full auto-enforcement capability. Thus two partial enforcements don’t equate to

a full enforcement.

If neither QA C++ or PC-Lint / Flexi-Lint were assessed to provide direct enforcement of a given

rule or guideline then the annotation ‘No auto’ was used to indicate that there was no automatic

Page 63: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

56

enforcement available from these two tools. To enforce such cases other tools would need to be

sought, or manual checks and controls would need to be employed.

Industrial Strength C++ Item Control Enforced

Rule 8.1 Delete should only be used with new. Rule 12.3 (direct) QAC++

Rule 8.2 Delete[] should only be used with new[]. Rule 12.3 (direct) QAC++

Rule 8.3 Do not access a pointer or reference to a deleted object. Rule 12.8 (avoids) QAC++ partial

PC-Lint partial

Rec 8.4 Do not delete this. New Rule (4) QAC++

Rec 8.5 If you overloaded operator new for a class, you should

have overloaded operator delete.

Rule 12.6 (direct) QAC++

Rec 8.6 Customise the memory management for a class if

memory management is an unacceptably large part of the

allocation and deallocation of free store objects of that

class.

Efficiency

Rec 9.1 Objects with static storage duration should be declared

only within the scope of a class, function, or anonymous

namespace.

Rule 8.1.1 (direct)

Rule 8.1.2 (direct)

Rule 8.2.2 (direct)

Guideline 6.6 (supports)

QAC++

QAC++

QAC++

No auto

Rec 9.2 Document how static objects are initialised. Rule 8.2.2 (direct)

Guideline 8.3.2 (avoids)

Maintenance

QAC++

No auto

Rule 10.1 Declare data members private. Rule 3.4.1 (direct) QAC++

Rec 10.2 If a member function returns a pointer or reference, you

should document how it should be used and how long it

is valid.

Maintenance

Rec 10.3 Selection statements (if-else and switch) should be used

when the control flow depends on an object’s value;

dynamic binding should be used when the control flow

depends on the object’s type.

Software Engineering –

Object Oriented Design

Rule 10.4 A public base class must have either a public virtual

destructor or a protected destructor.

Rule 3.3.2 (direct)

Guideline 17.7 (direct)

QAC++

No auto

Rule 10.5 If you derive from more than one base class with the

same parent, that parent should be a virtual base class.

Rule 3.3.15 (direct) QAC++

Rec 10.6 Specify classes using preconditions, postconditions,

exceptions, and class invariants.

Software Engineering –

Object Oriented Design

Malpas

Rec 10.7 Use C++ to describe preconditions, postconditions,

exceptions and class invariants.

Software Engineering –

Object Oriented Design

Rec 10.8 It should be possible to use a pointer or reference to an

object of a derived class whenever a pointer or reference

to public base class object is used.

Rule 3.3.3 (direct)

ISO C++ defines

QAC++

Rec 10.9 Document the interface of template parameters. Maintenance

Table 9: HICPP Coverage of Industrial Strength C++ Items (partial extract from Appendix 1)

Because MALPAS and Cantata++ are not used to enforce rules, but are instead analysis and testing

tools, they are not widely referenced in the tables in Appendixes 1 to 14. They are predominantly

used in supporting the work conducted in Sections 5 and 6.

The results of the assessment shall now be considered. To summarise briefly, the capability of these

tools for auto-enforcing the HICPP and additional rules and guidelines relating to C++ best practice

and OOTiA recommendations is substantial. However, complete auto-enforcement of every rule

and guideline is not possible with these tools. Less substantially, but still significant, are the tools’

capability for auto-enforcing the HICPP and additional rules and guidelines relating to the

unspecified, undefined, implementation-defined and indeterminate behaviours.

The capability of these tools for auto-enforcing the standard template library (STL) related rules and

guidelines is extremely limited. This relates to both the C++ STL best practice, problems and

solutions, as well as the unspecified, undefined and implementation-defined behaviours. Thus there

Page 64: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

57

is a need for the range of checks provided by QA C++ or PC-Lint / FlexeLint to be expanded with

respect to the STL rules and guidelines. Alternatively other tools are required to be identified or

developed. An auto-enforcement capability for the STL related rules and guidelines is particular

important as it provides the primary means of mitigating the base language array bounds problems.

QA C++ provides a significant proportion of the total enforcement capability, noting the limitations

placed on the PC-Lint / FlexeLint assessment. However there are a small number of cases where

PC-Lint / FlexeLint’s detection capabilities differ slightly to QA C++ and these are responsible for

those rules and guidelines against which it provides further enforcement.

It is probably also appropriate to raise the issue of rules and guidelines that don’t lend themselves to

enforcement. These are the types of rules and guidelines that often draw the sternest criticism due to

their potential ambiguity. Though it is arguably better to include a rule or guideline that only applies

in certain cases and is not auto-enforceable than to ignore such a possibility. The rules or guidelines

may not lend themselves to auto-enforcement because the rule or guideline does not lend itself to

static detection or because the rule or guideline relates to the higher level design development. In

such cases this should be highlighted and some level of traceability established between the static

analysis deficiencies and the dynamic test coverage. In addition there is scope for the development

of tools to detect unsafe higher level designs. QA C++ provides some capability for graphically

representing the class hierarchy and describing other higher level design issues. However these

diagrams and reports still require manual inspection to assess their correctness.

The rules and guidelines (shown in Appendix 15) are the most significant in lacking an auto-

enforcement capability. For each rule an assessment is made to determine if the case is statically or

dynamically detectable (or both in some cases). Each rule has also been assessed as to if it

represents a design issue, coding level detectable issue or is related to the coding environment. The

combination of these assessments will determine the likelihood that the rule can be auto-enforced.

Those rules or guidelines assessed as requiring enforcement of a design related issue (in particular

dynamic, but also applies to some static cases) will be the most difficult to provide a tool to auto-

enforce. These are numerous among those presented below and represent an area where auto-

enforcement is immature. It also works to identify those items that require specific design review,

or dynamic tests included as part of the test program.

4.5 Summary of Definition of Safer C++ Subset

Section 4.1 has examined HICPP against C++ behaviours, best practice (problems and solutions)

and the OOTiA recommendations. From this Section 4.2 has identified deficiencies in HICPP and

has developed additional rules and guidelines to address these deficiencies. This combination of the

HICPP rules and guidelines and the addition rules and guidelines shall be known as the safer C++

subset. Section 4.3 has identified and reasoned about those rules within HICPP that were not

referenced in the assessment. Finally Section 4.4 has examined the enforcement of the rules and

guidelines of the safer C++ subset.

Page 65: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

58

5 Arguments for Programming Language Selection

A number of the standards covered in Section 2.3 detailed that the selection of programming

language for a safety critical system should be justified and that a safety case should be produced.

Thus it is worth examining what means could be used to argue justification for the selection of

programming language within the context of a system’s safety case. Section 2 examined a broad

range of literature and standards that provide guidance relating to the selection of a programming

language for a safety critical system. Generally, individual sources presented guidance as an

unrelated set of language criteria. An inspection of this guidance revealed numerous themes within

the totality of this information. The identified themes include:

• Only the completely and unambiguously defined aspects of the programming language should

be used. Ambiguously and poorly defined aspects of the language should be avoided.

• The language must support recognised software engineering principles. Such principles

include strongly typed features, a modular and structured approach, abstraction, encapsulation

and information hiding.

• The language must be well understood by programmers and developers and this must support

the correct implementation of the design.

• The language’s implementation of its paradigm and features must support the design method,

domain, and application.

• The language must lend itself to static analysis and dynamic testing, the totality of which is

sufficient to provide confidence in the safety of the software.

• High quality, certified or verified language translators, analysis and support tools must be

available for the language.

These themes certainly seem relevant, but they lack an important component that is required when

constructing a justifiable argument. The themes lack ‘why’ they are important. Thus a particular

focus of the argument construction will be in determining ‘why’ these factors make a programming

language suitable. The construction of the argument is also going to serve as an evaluation of these

criteria. For example, if criteria are stipulated, but are found to not be required to form a justifiable

argument, then are they useful criteria? Likewise, are there deficiencies in the criteria that prevent a

justifiable argument being made?

Section 5.1 examines the construction of an argument for justifying the selection of a programming

language. The argument presented here is evaluated in Section 6.1.

5.1 GSN Argument for Programming Language Selection

An argument pattern has been developed and is presented in Appendix 16. Goal Structuring

Notation (GSN) was identified in Section 2.8 as a suitable tool for developing and expressing the

argument. This section describes the activity of developing the pattern and should be read in

conjunction with the pattern in Appendix 16 (Figures 16-1 to 16-11). The pattern is intended to be

applied to the justification of potentially any programming language. The pattern has also been

developed to ensure coverage of the criteria specified in IEC 61508, DO-178B, and Defence

Standard 00-55 Issue 2. Thus its structure has been deliberately developed to be flexible.

Page 66: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

59

The first step of the GSN process, as described by [HRM04], is to identify and define the top-level

goal. Thus the overall objective of the argument must be established. This is important because if it

doesn’t contain the right aim, then the argument may be difficult to satisfy. Section 1.2 identified

safety as a system property. This is important as it highlights that, while the selection of the

programming language can certainly contribute to the safety of the system, it is unreasonable to

conclude that in isolation a programming language is safe. Hence, defining a top level goal as

‘{Lang X} is acceptably safe’ or ‘{Lang X} is acceptably safe for {System Y}’ is not appropriate.

There should be a goal stating ‘{System Y} is acceptably safe’, but this does not belong in the

language justification.

A programming language can certainly introduce errors into a design, as can it introduce

unnecessary complexity into the implementation of an otherwise simple design. Thus it seems

reasonable that these are the properties that an argument should conclude a programming language

shouldn’t have. Furthermore, arguing the safety of the design is not the responsibility of an

argument centred on the selection of the programming language. This is the realm of the software

design safety argument that, because safety is a system property, will be embedded within an

overall system safety argument. The system safety argument also includes such factors as hardware,

environment, people, processes and standards. Thus, assuming that the software design, and the

system for that matter, is shown to be acceptably safe, then it follows that the programming

language selection should primarily be concerned with correctly implementing the acceptably safe

design. Hence, the top level goal is established as ‘{Lang X} supports the correct implementation of

{System Y}’s software design’. In some respects this is related to the Software Fault Free Pattern in

[HRM04].

Having established the top level goal (Figure 15 below), the next step is to define the basis on

which that goal is being stated. A programming language does not exist in isolation, nor does it

implement the design itself – though that would be a useful feature. Code in a given programming

language will always be written either by programmers or by tools that were written by

programmers. Thus a programming language’s ability to correctly implement a design is not only a

function of its own properties, but also on the programmers using it and the tools (translators,

environments, analysis and test, etc) supporting it. Furthermore, the role of the programming

language does not cease the moment the system enters service. Systems change, and the

programming language must also correctly support the system through these changes and

throughout its operational lifetime. This leads us to the three main strategies employed in the

argument (Figure 15). These are as follows.

• S1 – Argument over {Lang X} supporting the correct implementation of the design during

initial development and during {SystemY}’s operational lifetime.

• S2 – Argument over the programmers’ roles in correctly implementing {System Y}’ssoftware design.

• S3 – Argument over the tools’ roles in correctly implementing {System Y}’s software design.

S1 is certainly to be the bulk of the argument. However, the importance of S2 and S3 is supported

by their inclusion at this high level within the goal structure. S1 can be logically divided into two

supporting goals relating to the correct implementation during initial development (G1.1) AND the

correct implementation over the system’s operational lifetime (G1.2). G1.2 is supported by a

number of goals, but the emphasis is on identifying those features of the language that can support

the communication of the original programmers’ intentions to the future maintainers. For example,

user documentation and comments (G1.2.1), and coding style guidelines for consistency and

maintenance (G1.2.2) are considered the minimum required (see Figure 16-1).

Page 67: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

60

G.TOP

{LangX} supports the

correct implementation of

{SystemY}'s software

design

C.TOP.2

{SystemY} definition

G1.2

{LangX} features support

maintaining the

implementation over

{SystemY}'s operational

lifetime

S1

Argument over {LangX}

supporting the correct

implementation of the

design during initial

development and during

{SystemY}'s operational

lifetime

G1.1

{LangX} supports the

correct implementation of

the design during initial

development of {SystemY}

G2.1

{LangX} is well understood

by the programmers and

this supports the correct

implementation of the

design

S2

Argument over the

programmers' roles in

correctly implementing

{SystemY}'s software

design

S3

Argument over the tools'

roles in correctly

implementing

{SystemY}'s software

design

G3.1

Tools for development in

{LangX} support the

correct implementation of

{SystemY}'s software

design

A.TOP

{SystemY}'s software

design is shown to be

acceptably safe

elsewhere A

C.TOP.1

{LangX} definition

Figure 15: Top Level Argument (partial extract from Figure 16-1)

Correctly implementing the design during the initial development (G1.1) reduces to two diverse

relationships (Figure 16 below). The language must have features suitable to implement the design

(S1.1B). For example, if the design is a multi-threaded design, and the language only supports

single threaded applications, then there may be problems. Likewise if the language requires

interfaces to modules written for the application in other languages, and it doesn’t support them,

then the language is also probably the wrong choice. Furthermore, there must be a means of

preventing AND/OR detecting all errors made in the implementation of the design (S1.1A).

Detecting errors as it is described here is concerned with detecting the errors during analysis or

testing of the system, and prior to any operational testing or operational release. This is different to

the notion of run-time error detection and handling which is included as part of the error prevention

argument (G1.1A.1). This is because this has been classified as a means of actually preventing fatal

run-time errors during system operation (ie. it gives the software the option of recovering or failing

safe). Note the use of the AND/OR conjunction. This is important because, depending on the

language, the balance of prevention (G1.1A.1) and detection (G1.1A.2) may vary. The pattern

supports this notion with the n-of-2 option symbol. These two goals also relate to the choice of

design philosophy identified in Section 1.2. The remainder of the argument is focussed on

supporting these two goals (G1.1A.1 and G1.1A.2).

G1.1

{LangX} supports the

correct implementation of

the design during initial

development of {SystemY}

S1.1A

Argument over means of

preventing and/or

detecting errors

S1.1B

Argument over features

required by {LangX} in

order to implement the

design

G1.1A.1

Occurrences of errors in

the implementation of the

design in {LangX} are

prevented

G1.1A.2

Occurrences of errors in

the implementation of the

design in {LangX} are

detected

G1.1B

{LangX} supports

{FeatureZ} that is required

in order to correctly

implement the design

n-of-2

n

Figure 16: Correct Implementation Argument (partial extract from Figure 16-1)

Page 68: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

61

5.1.1 Supporting Goal G1.1A.1 (in Appendix 16 Figure 16-2)

G1.1A.1 is defined as ‘Occurrences of errors in the implementation of the design in {Lang X} are

prevented’ (Figure 17 below). Now presuming that the programmers’ are actually capable of

writing code that will compile (ie. is grammatically correct – A1.1A.1), and the compiler is the least

bit useful at pointing out grammatically incorrect source code, then that leaves two places that

errors could occur in the implementation of the design. Thus, the argument should be focussed to

prevent these errors.

G1.1A.1.2

Occurrences of run-time

errors in the

implementation of the

design are prevented

S1.1A.1

Argument over

instances at which

errors that might occur

in the implementation of

the design

G1.1A.1

Occurrences of errors in

the implementation of the

design in {LangX} are

prevented

G1.1A.1.1

Errors are not introduced

in the translation of the

implementation (source

code) into executables

A1.1A.1

Source code is

grammatically correct

A

Figure 17: Error Prevention Argument (partial extract from Figure 16-2)

Errors that may manifest themselves at run-time should not have been introduced in the

implementation of the design (G1.1A.1.2 –Figure 18 below). These may be caused by either aspects

of the language which behave unpredictably (S1.1A.1.2A), despite the programmers understanding

of them, or aspects of the language which get used incorrectly because they are error prone or

because programmers don’t understand them properly (S1.1A.1.2B). Sections 5.1.1.1 and 5.1.1.2

further address the development of these strategies. Also, errors should not be introduced in the

translation of the implementation (source code) into executables (G1.1A.1.1 – see Figure 16-2).

This is out of the programmers’ control and responsibility lies with the translator (compiler). Thus it

is important to be able to reason that errors are either absent from the translator (G1.1A.1.1.1), or

are known and can be avoided (G1.1A.1.1.2). Supporting these goals may be more difficult than it

would seem. To show that errors are absent from a translator then the translator must have been

subjected to some form of formal verification. Alternatively, showing that all errors are known in a

translator can be equally as difficult, especially if the translator is not widely used.

G1.1A.1.2B.1

Sources of commonly

introduced run-time errors

are identified and avoided

G1.1A.1.2B.2

{LangX} supports the

application of design

techniques that avoid and

mitigate run-time errors

G1.1A.1.2

Occurrences of run-time

errors in the

implementation of the

design are prevented

S1.1A.1.2B

Argument over means of

avoiding, mitigating,

detecting and handling

non-definition related

errors at run-time

G1.1A.1.2A.1

Only completely and

unambiguously defined

aspects of {LangX} are

used for {System Y}

S1.1A.1.2A

Argument that no errors,

omissions or

inconsistencies relating

to {LangX}'s definition

will contribute to run-

time errors in the

implementation of the

design

C1.1A.1.2A

{LangX} definition

G1.1A.1.2B.3

{LangX} supports a robust

run-time error detection

(or exception) system and

handling mechanism

Figure 18: Run-time Error Argument (partial extract from Figure 16-4)

Page 69: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

62

5.1.1.1 Arguing strategy S1.1A.1.2A (Definition Related Errors – Appendix 16 Figure 16-4)

Language behaviour is a function of the language definition. Thus one strategy of supporting

G1.1A.1.2 would be to argue that no language definition issues will contribute to run-time errors in

the implementation of the design (S1.1A.1.2A → G1.1A.1.2A.1 – Figure 19). There should only be

one definition of the language (S1.1A.1.2A.1A – Figure 19), as multiple definitions of the same

language works against the programmer’s chances of understanding the language. The best means

of ensuring only one language definition is for the language to be internationally standardised

(G1.1A.1.2A.1A.1 and G1.1A.1.2A.1A.2).

Even if there is only one definition of the language, then it may not be complete. This identifies the

second strategy (S1.1A.1.2A.1B – Figure 19). Language definition standards, even international

ones, are littered with unspecified, undefined, indeterminate and implementation-defined

references. Thus, either the language definition’s completeness must be ascertained

(G1.1A.1.2A.1B.1), which is rare, or those behaviours that are not completely and unambiguously

defined must be restricted through some form of subset (G1.1A.1.2A.1B.2 – Figure 16-6).

G1.1A.1.2A.1A.1

Base language of

{LangX} has been

internationally

standardised

S1.1A.1.2A.1A

Argument that the

standardisation of

{LangX} eliminates

ambiguities relating to

variations in definition

G1.1A.1.2A.1B.1

{LangX} has no

unspecified, undefined,

indeterminate and

implementation defined

behaviours

G1.1A.1.2A.1B.2

A subset of {LangX}

sufficiently restricts the

unspecified, undefined,

indeterminate and

implementation defined

behaviours of {LangX}

G1.1A.1.2A.1A.2

Library support for

{LangX} has been

internationally

standardised

G1.1A.1.2A.1

Only completely and

unambiguously defined

features of {LangX} used

for {System Y}

S1.1A.1.2A.1B

Argument that only the

completely and

unambiguously defined

features of {LangX} are

to be used

Figure 19: Definition Argument (extract from Figure 16-5)

5.1.1.2 Arguing strategy S1.1A.1.2B (Non-definition Related Errors – Figure 16-4)

S1.1A.1.2B is defined as “Argument over means of avoiding, mitigating, detecting and handling

non-definition related errors” (Figure 18). This is perhaps the most difficult aspect of the entire

language argument. This is because it is difficult to truly ascertain just what errors programmers are

likely to make. Thus the argument must use a number of diverse argument approaches in order to

provide confidence that G1.1A.1.2 will be supported. One approach is to claim that a lot is known

about a language, its problems, and that it is possible to address these problems (G1.1A.1.2B.1). In

some respects this is reflective of the work conducted for C++ in Sections 3 and 4. But how are

errors that are not known about prevented? After all, to argue across all errors, the argument needs

to include both known and unknown errors. To support this it is possible to also claim that the

language can support design techniques that avoid and mitigate run-time errors (G1.1A.1.2B.2) and

that should an error occur, even an unknown one, then it could be detected and handled

(G1.1A.2B.3). Because the error has been successfully detected at run-time and there is a

predictable mechanism for the software to recover or fail safe then it is no longer considered an

error through which the timing, resource usage and functionality of the software becomes

unpredictable.

Page 70: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

63

Thus to support G1.1A.1.2B.1, the main types of errors must be identified. In turn these sources of

errors could be related to those features of, or restrictions on, the language that prevent such errors

(Figure 20). Hence, a list of the types of errors that can occur in software is required. Recalling that

software is composed of data and the operations on that data, then it follows that errors could be

resident in either of these. An error in the data (ie. data related) is straight forward to comprehend,

but an error in an operation is going to be caused either because the data is in error (also data

related), or because the sequence of sub-operations comprising the overall operation is changed

(control flow related). Note also that software must execute on real world hardware. Thus these

external influences have the potential to inflict errors upon the software. For example, resources are

related to a finite number of hardware elements (resource availability related), and real world

hardware does not execute instructions instantaneously (ie. timing is a property). Timing properties,

although hardware related, also are impacted by the sequence of operations within the software

(control flow related). Finally it is also possible for certain instructions to be in error and for the

hardware to cease operating (run-time exception / abnormal program termination), operate

incorrectly (run-time exception / control flow related), or for the system to be reset (control flow

related) or recover (run-time exception / control flow related). Thus the list of the types of errors

that can occur in software becomes:

• Data Related: a variable, memory location, or object contains an incorrect or invalid valuedue to the occurrence of an error.

• Control Flow Related: the path of execution through the code is changed because of the

occurrence of the error and thus the operations on the data are changed.

• Run-time Exceptions / Abnormal Program Termination: a specific instruction cannot be

executed or executes unpredictably due to the occurrence of the error. For many languages the

run-time system may either terminate the program (undesirable), or the system may be left

hanging (also undesirable).

• Resource Availability: the occurrence of the error has impacted upon the ability of the system

to make appropriate resources available to the system.

G1.1A.1.2B.1 is defined as ‘Sources of commonly introduced run-time errors are identified and

avoided” (Figure 20). By arguing across each of the error types identified above, the goal can be

supported. A programming language has properties. Software engineers often find names for groups

of these properties that include such things as typing (G.TYPE), variable initialisation

(G.VARIABLES), mathematical model (G.MATH), paradigm (G.PARADIGM), side effects in

expression (G.SIDE), scopes, blocks and jumps (G.JUMPS), and memory model (G.MEMORY).

Another property of a programming language is just how prone its syntax is to typos

(G.MISTAKES). Each of these properties can lead to one or more of the error types (data, control

run-time exception / abnormal program termination, resource availability). Thus each error type

must be argued over all the language properties that can relate to that particular error type. Figure

20 shows the complex relationships between these properties.

For new programming languages and advanced software / hardware relationships, it may be

possible that errors may not totally lend themselves to classifications under data related, control

flow related, run-time exception/abnormal termination related, and resource availability related.

Thus G1.1A.1.2B.1.5 (Figure 16-8) provides a means of arguing that such errors are known about

and can be restricted.

Page 71: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

64

G.SIDE_EFFECT.1

{LangX} is not prone to

side effects in expression

G.MISTAKES

{LangX} has features to

facilitate the detection of

programming typos and

unintentional mistakes

G.JUMPS.1

{LangX} supports a

modular, structured

approach (restrictions on

jumps between scopes)

G.VARIABLES.1

Declaration and

initialisation of variables is

explicit

G.TYPE.1

{LangX} is strongly typed

to ensure type safety and

to avoid type related

errors at run-time

G.VARIABLES

Uninitialised and implicitly

initialised variables that

are a likely source of error

at run-time are avoided

G.SIDE_EFFECT

Side effects in expression

that are a likely source of

error at run-time are

avoided

G.MISTAKES

Unintentional

programming mistakes

that are a likely source of

run-time error are avoided

S1.1A.1.2B.1

Argument across the

identified sources of

commonly introduced

run-time errors

G.JUMPS

Jumps between scopes

that are a likely source of

error in an implementation

of a design are avoided

G.TYPE

Type related features that

are a likely source of error

at run-time are avoided

G.PARADIGM.1

{LangX}'s implementation

of the paradigm's features

is error free

G1.1A.1.2B.1

Sources of commonly

introduced run-time errors

are identified and avoided

J1.1A.1.2B.1

Identified sources of

commonly introduced

run-time error are

adequate

G.PARADIGM

Paradigm related sources

of commonly introduced

run-time errors are

avoided

G1.1A.1.2B.1.1

Data related sources of

commonly introduced run-

time errors in an

implementation are

restricted

G1.1A.1.2B.1.2

Control flow related

sources of commonly

introduced run-time errors

in an implementation are

restricted

G1.1A.1.2B.1.4

Resource availability

related sources of

commonly introduced run-

time errors in an

implementation are

restricted

G.MEMORY

Memory allocation/

deallocation activities that

are a likely cause of error

in an implementation of a

design are avoided.

G.MEMORY.1

{LangX} is not prone to

memory leaks

G.MATH

Mathematical operations

and results that are a

likely source of error at

run-time are avoided

G.MATH.1

{LangX} is not prone to

invalid mathematical

operations and results

G1.1A.1.2B.1.5

Other sources of

commonly introduced run-

time errors in an

implementation of a

design are restricted

G1.1A.1.2B.1.3

Run-time exceptions

leading to abnormal

program termination in an

implementation are

restricted

J

Generic language argument

shall address all relationships.

Some relationships may be

simplified in relation to the

specific design context of

{SystemY}.

Figure 20: Common Error Sources Argument (extract from Figure 16-7)

5.1.2 Supporting Goal G1.1A.2 (Detecting Errors – in Appendix 16 Figure 16-3)

G1.1A.2 is defined as “Occurrences of errors in the implementation of the design in {Lang X} are

detected” (Figure 21). Similarly to arguing G1.1, this goal may be supported through two diverse

arguments. Primarily, there must be a means of showing that errors in the implementation of the

design would be detected through some form of analysis and verification (S1.1A.2A). Recognising

that analysis and verification can be satisfied with either static analysis, dynamic testing, or ideally

a combination of both, the important point that needs to be established is that the totality of these

activities provides sufficient confidence that all necessary properties of the software implementation

have been revealed. Noting the numerous benefits of static analysis detailed in Section 2.9, the

pattern seeks to promote the use of static analysis to analyse and verify a significant proportion of

the implementation of the design (G1.1A.2A.1). The word “significant” has been used as it

indicates a substantial amount of static analysis, but recognises that rarely can static analysis be

used in isolation. Dynamic testing must then be sought to complement the static analysis (ie. make

total the analysis and verification) (G1.1A.2A.2).

Returning to supporting the goal G1.1A.2. The secondary aspect is to argue that it may also be

possible to argue that the language has features that actually facilitate the detection of errors in the

design or in the implementation of the design (S1.1A.2B). This seeks to alleviate some of the

pressures on the analysis and verification activities. As a minimum these features should include

restricting the complexity of the implementation (G1.1A.2B.1), as complex implementations are

rarely correct, and using abstraction and information hiding to detect operations that may violate

data integrity (G1.1A.2B.2). For example, the hiding of the internal state of an object, and allowing

access only through specified functions or methods, will detect problems of external modules

attempting to directly access the object’s internal state.

Page 72: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

65

ref. Figure P-9G1.1A.2B.1

{LangX} has features to

restrict and manage

complexity

S1.1A.2B

Argument over types of

implementation features

that facilitate the

detection of errors in the

design

G1.1A.2A.2

{LangX} lends itself to

dynamic testing to

complement the static

analysis

S1.1A.2A

Argument to show that

errors in the design

would be detected

though analysing and

verifying the

implementation in

{LangX}

G1.1A.2A.1

{LangX} lends itself to a

significant proportion of

static analysis

G1.1A.2B.2

{LangX} supports

abstraction and

information hiding

G1.1A.2

Occurrences of errors in

the implementation of the

design in {LangX} are

detected

G1.1A.2B.3

{LangX} supports other

features that facilitate the

detection of errors in the

design

Figure 21: Error Detection Argument (extract from Figure 16-3)

5.1.2.1 Supporting Goal G1.1A.2A.1 (Static Analysis – Appendix 16 Figure 16-10)

G1.1A.2A.1 is defined as ‘{Lang X} lends itself to a significant proportion of static analysis’

(Figure 22). This leads to the question of what is required of a language in order to perform static

analysis. To support this goal, it is necessary to argue a number of things. Firstly, unless necessary

for the design, it is vital to limit those features which inhibit static analysis (S1.1A.2A.1A). As a

minimum such features include limiting dynamic variables (G1.1A.2A.1A.1), interrupts

(G1.1A.2A.1A.2), and recursion (G1.1A.2A.1A.3). If necessary, then the use of such features shall

be specifically justified for the design. For example, while the recursive implementation of an

algorithm may appear simple in the source code, the truth is that it is rarely going to be more

efficient (due to repeated numbers of function calls and the associated overhead) than it’s iterative

equivalent. Its resource usage is also going to be difficult to analyse. Thus justification should be

based on clarity, correctness, performance, efficiency, analysability, and testability, not just

convenience.

Secondly, it is necessary to argue that the language is statically predictable where required

(S1.1A.2A.1B). As a minimum the aspects that should be statically analysable are the resource

usage behaviour (G1.1A.2A.1B.1), the temporal behaviour (G1.1A.2A.1B.2), and the functional

behaviour (G1.1A.2A.1B.3) of the language. Ascertaining these behaviours will adequately

demonstrate the absence of the error types listed in Section 5.1.1.2. A valid means or a combination

thereof (indicated by the n-of-4/5 option) for statically analysing functional behaviour includes

control, data and information flow analysis (G1.1A.2A.1B.3.1), precondition, postcondition and

invariant analysis (G1.1A.2A.1B.3.2), formal code verification (G1.1A.2A.1B.3.3) and symbolic

execution (G1.1A.2B.1B.3.4). The pattern also provides flexibility for arguing other appropriate

means of satisfying these goals.

Finally in achieving G1.1A.2A.1, the strategy must also be cognisant of what the relevant standards

specify in relation to static analysis (S1.1A.2A.1C). Some standards are particularly prescriptive

with regards to the types of analysis to be performed. Thus it would be undesirable to apportion the

static analysis and dynamic testing such that, although total in coverage, the testing does not meet

the relevant standards. If standards are goal based, then the argument provides the flexibility to

argue alternate apportionment.

Page 73: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

66

G1.1A.2A.1A.1

Use of dynamic variables

is restricted except where

justifiably necessary

G1.1A.2A.1B.3.1

{LangX} lends itself to

control flow, data flow, and

information flow analysis

G1.1A.2A.1B.1

{LangX}'s run-time

resource usage is

analysable and

predictable

G1.1A.2A.1A.3

Use of recursion is

restricted except where

justifiably necessary

G1.1A.2A.1A.2

Use of interrupts is

restricted except where

justifiably necessary

G1.1A.2A.1A

{LangX} features that

inhibit the capabilities of

static analysis are

restricted

G1.1A.2A.1B.3.2

{LangX} support the use of

assertions/annotations in

analysing preconditions,

postconditions and

invariants

G1.1A.2A.1

{LangX} lends itself to a

significant proportion of

static analysis

S1.1A.2A.1A

Argument over a

restriction on those

features of {LangX} that

inhibit static analysis

G1.1A.2A.1B.3.4

{LangX} lends itself to

symbolic execution

G1.1A.2A.1B.2

{LangX}'s temporal

behaviour is analysable

and predictable

G1.1A.2A.1B.3

{LangX}'s functional

behaviour is analysable

and predictable

G1.1A.2A.1B.3.3

{LangX} lends itself to

formal code verification

(formal methods)

S1.1A.2A.1B

Argument that {LangX}

is predictable and that it

lends itself to static

analysis

S1.1A.2A.1C

Argument that static

analysis of {LangX}

meets the relevant

standards

G1.1A.2A.1C

Static analysis of {LangX}

meets the relevant

standards

C1.1A.2A.1

Definition of "significant

proportion"

C1.1A.2A.1C

Identified relevant

standards

G1.1A.2A.1A.4

Use of other {LangX}

constructs that inhibit the

capabilities of static

analysis is restricted

S1.1A.2A.1B.3

Argument over means of

analysing {LangX}'s

functional behaviour

n-of-4/5

G1.1A.2A.1B.3.5

Other means of analysing

{LangX}'s functional

behaviour are used

Figure 22: Static Analysis Argument (extract from Figure 16-10)

5.1.2.2 Supporting Goal G1.1A.2A.2 (Dynamic Testing – Appendix 16 Figure 16-11)

G1.1A.2A.2 is defined as ‘{Lang X} lends itself to dynamic testing to complement the static

analysis’ (Figure 23 below). To support this goal, it is necessary to argue that the appropriate

aspects of the language’s behaviour are dynamically testable (S1.1A.2A.2A). Appropriate aspects to

dynamically test will be based on the coverage and limitations of the statically analysable aspects of

the language. This provides context for supporting this strategy (C1.1A.2A.2A). As a minimum the

aspects that should be dynamically testable are the temporal behaviour (G1.1A.2A.2A.1), the

resource usage behaviour (G1.1A.2A.2A.2) and the functional behaviour (G1.1A.2A.2A.3) of the

language.

In achieving G1.1A.2A.2, the strategy must also be cognisant of what the relevant standards specify

in relation to dynamic testing (S1.1A.2A.2B). Some standards are particularly prescriptive with

regards to the types and numbers of tests to be performed. Thus, reiterating what was stated for

static analysis apportionment, it would be undesirable to apportion the static analysis and dynamic

testing such that, although total in coverage, the testing does not meet the relevant standards. If

standards are goal based, then the argument provides the flexibility to argue alternate

apportionment.

Page 74: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

67

G1.1A.2A.2

{LangX} lends itself to

dynamic testing to

complement the static

analysis

G1.1A.2A.2A.2

{LangX}'s run-time

resource usage is testable

and predictable

G1.1A.2A.2A.1

{LangX}'s temporal

behaviour is testable and

predictable

G1.1A.2A.2A.3

{LangX}'s functional

behaviour is testable and

predictable

S1.1A.2A.2B

Argument that dynamic

testing of {LangX} meets

the relevant standards

G1.1A.2A.2B

Dynamic testing of

{LangX} meets the

relevant standards

S1.1A.2A.2A

Argument that

appropriate aspects of

{LangX}'s behaviour are

dynamically testable.

C1.1A.2A.2A

Identified coverage and

limitations of the statically

analysable aspects of

{LangX}

C1.1A.2A.2B

Identified relevant

standards

Figure 23: Dynamic Testing Argument (extract from Figure 16-11)

5.2 Summary of GSN Argument for Programming Language Selection

Section 5 has presented the development and definition of an argument for justifying the

programming language selection for safety critical systems. The argument has been developed to

incorporate reasoned inclusion of those language criteria reviewed in Section 2.2.

In fact, all of the criteria from Section 2.2 and the themes derived from these criteria (Section 5)

have been found to be necessary in the construction of the goal structure. Also there were no

specific deficiencies in the criteria required to support such an argument.

The argument has now developed the ‘why’ that was previously not evident directly from the

criteria. Section 6.1 seeks to evaluate the validity and usefulness of the pattern.

Page 75: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

68

6 Evaluation of Safer C++ Subset and Safety Arguments

Section 4 established a safer C++ subset (HICPP coding standard and additional rules and

guidelines). Section 5 developed a means of arguing the justification of the language selection. This

section now presents several evaluations of the material developed in each of these preceding

sections.

Section 6.1 examines the safer C++ subset against the justification of programming language

selection pattern. Section 6.2 examines the safer C++ subset against the safe language criteria

established in Section 2.2.3. Section 6.3 examines proposals for further evaluating the safety

arguments associated with programming language selection in general, and the safety arguments

associated with the specific selection of the C++ programming language for safety critical systems.

The intention of these evaluations is to identify any deficiencies in either the safer C++ subset or

with the justification of programming language selection argument pattern and how these might be

addressed.

6.1 Evaluation of Safer C++ Subset Against GSN Argument

Section 5.1 developed a safety case pattern for the justification of the selection of programming

language for safety critical systems. The pattern is presented in Appendix 16. Given that this project

has principally concerned itself with an examination of C++ in the context of safety critical

systems, it is worthwhile to evaluate this pattern against the safer C++ subset developed in Sections

3 and 4. The aim of the evaluation is to uncover deficiencies in either the pattern or the safer C++

subset with respect to each other. Note that because many aspects of the pattern require knowledge

of the specific system and design context, instantiation of these goals may be limited to discussion

as to if it is possible to satisfy these goals for C++ and how this might be approached.

Evidence in support of many of the following goals is provided through reference to specific rules

within the safer C++ subset. It is important to note that the rules require enforcement either through

tools or manually. Enforcement of the rules and guidelines was addressed in Section 4.4.

6.1.1 Translator Goals – Figure 16-2

6.1.1.1 G1.1A.1.1.1.1 – Formally Proven / Fully Verified Compiler

Supporting this goal relies on specific system design information relating to the target processor and

environment. It is also related to satisfaction of the chosen language standardisation

(G1.1A.1.2A.1A.1 and G1.1A.1.2A.1A.2) goals. Section 6.1.2 discusses that the C++ language has

been ANSI/ISO standardised. Fully verified and/or formally proven C++ compilers are not widely

available at this time. In addition, many compilers are yet to achieve full ANSI/ISO compliance.

Numerous organisations exist that can offer certification services for a compiler against the

ANSI/ISO C++ standard and these may offer a means of satisfying this goal.

6.1.1.2 G1.1A.1.1.2.1 and G1.1A.1.1.2.2 – Translation Error Avoidance

Supporting this goal relies on specific system design information relating to the target processor and

environment. C++ compilers are becoming more widely available for many target systems, due

mainly to C++ popularity in the commercial sector. These compilers are well documented and

identified problems are widely reported on numerous internet newsgroups and compiler developer’s

websites. It is possible to support G1.1A.1.1.2.1 through providing evidence derived from such

sources. A specific coding standard would then need to be developed for the project to limit the use

of those known sources of error in translation. This could be used as evidence to support

G1.1A.1.1.2.2.

Page 76: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

69

6.1.2 Language Standardisation Goals – Figure 16-5

6.1.2.1 G1.1A.1.2A.1A.1 and G1.1A.1.2A.1A.2 – International Standardisation

The C++ base language and standard template library (STL) has been internationally ANSI/ISO

standardised [BSI03]. Reference to [BSI03] should be considered sufficient evidence to support

these goals for C++. Several rules in the safer C++ subset provide restrictions of common features

that are not actually part of ISO C++, but get commonly used in implementations regardless. These

are Rules 6.4, 8.3.1, 10.16, 17.1, & 17.8.

6.1.3 Language Behaviour Goals – Figures 16-5, 16-6

6.1.3.1 G1.1A.1.2A.1B.1 – Fully Defined Behaviour

The C++ language definition [BSI03] contains many references to unspecified, undefined,

indeterminate and implementation-defined behaviour. Thus this goal cannot be supported and

G1.1A.1.2A.1B.2 must instead be supported.

6.1.3.2 G1.1A.1.2A.1B.2 – Restricted Behaviour

Unspecified (G1.1A.1.2A.1B.2.2), undefined (G1.1A.1.2A.1B.2.1), indeterminate

(G1.1A.1.2A.1B.2.4), and implementation-defined (G1.1A.1.2A.1B.2.3) behaviours of C++ are

restricted through the safer C++ subset. Appendixes 8 – 14 have identified a complete list of these

behaviours and also list those rules applicable to restricting these C++ behaviours. Appendixes 8 –

14 would be suitable as evidence for supporting these goals.

6.1.4 Strongly Typed Goals – Figure 16-9

6.1.4.1 G1.1A.1.2B.1.1.1.1.1.1 – Implicit Conversions

Evidence is required to support this goal that shows that implicit conversions do not occur.

Although C++ supports numerous cases of implicit conversions, the following rules and guidelines

prohibit implicit conversions in C++ and thus support strong typing: Rules 3.1.10, 3.1.11, 3.2.3,

3.5.4, 7.8, 8.3.5, & 16.1 and Guidelines 8.4.13, 10.7, & 17.21.

6.1.4.2 G1.1A.1.2B.1.1.1.1.1.2 – Explicit Conversions

Evidence is required to support this goal that shows that explicit conversions only occur when

justified and desired. C++ supports numerous cases of explicit conversions, and the following rules

and guidelines control the use of explicit conversions in C++ and thus support strong typing: Rules

3.1.2, 3.3.3, 3.3.4, 7.1, 7.3-7.7, & 15.4 and Guideline 7.2.

6.1.4.3 G1.1A.1.2B.1.1.1.1.2.1 – Array Bounds Checking

Evidence is required to support this goal that shows that all accesses to arrays are demonstrably

within the bounds of the array. Although C++ arrays lack array bounds checking and enforcement,

the following rules support array type structures with adequate array bounds checking and thus

support strong typing: Rules 8.4.8, 8.4.9, 10.2, & 24.

6.1.4.4 G1.1A.1.2B.1.1.1.1.2.2 – Access Types and Pointers

Evidence is required to support this goal that shows that access types and pointers are only used

where justifiably necessary. C++ provides both pointer and reference access types. The programmer

is not forced to use such types, but certain designs and/or STL features may require their use.

Software designers and programmers should limit the use of these types to those aspects of the

design where their use is necessary and justifiable. Guideline 8.4.10 supports a restriction on access

types in support of strong typing.

Page 77: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

70

6.1.4.5 G1.1A.1.2B.1.1.1.1.3.1 – Support for Static Types

Evidence is required to support this goal that shows that C++ supports static types including sub-

types and enumerations. C++ supports subtypes through public inheritance [BSI03]. C++ also

includes direct support for an enumeration primitive type [BSI03]. The following rules and

guidelines place restrictions on C++ types to strengthen their static characteristics: Rule 15.1 and

Guidelines 3.4.7, & 8.4.6.

6.1.4.6 G1.1A.1.2B.1.1.1.1.3.2 – Statically Analysable

Evidence is required to support this goal that shows that C++ types are statically analysable. With

the exception of access and pointer types, C++ POD types are statically analysable. Some uses of

access and pointer types are also statically analysable. Rule 15.1 places a restriction on C++ types

to improve static analysability. C++ class types support the use of polymorphism and dynamic

binding. Such mechanisms aren’t always statically analysable and evidence of appropriate other

tests (dynamic) should be identified to address the deficiencies and reveal the software properties

that would otherwise be revealed through static analysis.

6.1.4.7 G1.1A.1.2B.1.1.1.1.4 – Run Time Checking

Evidence is required to support this goal that shows that run-time checking is carried out on C++

types at run-time. The fact that G1.1A.1.2B.1.1.1.1.1 and G1.1A.1.2B.1.1.1.1.2 are adequately

supported means that evidence is only required to demonstrate that types remain within their ranges

and do not overflow or underflow. Although the C++ run-time machine does not usually support

overflow/underflow checking, these activities can be achieved through appropriate design and

application of defensive programming techniques (G1.1A.1.2B.2A.1 – defensive programming

goal) or assertion checking (G1.1A.1.2B.2A.2).

6.1.5 Sources of Run-time Error Goals – Figures 16-7, 16-8

6.1.5.1 G.VARIABLES.1 – Variable Declaration and Initialisation

Evidence is required to support this goal that shows that variable declaration and initialisation is

explicit. C++ supports a wide range of variable declaration and initialisation expressions.

Restrictions are required if this goal is to be supported. The following rules and guidelines support

explicit variable declaration and initialisation: Rules 3.1.2, 8.2.1, 8.2.2, 8.3.3 – 8.3.5, 8.4.2 – 8.4.4,

8.4.11, 11.7, 14.17 & 15.2 and Guideline 8.1.1 – 8.1.3, 8.2.3, 8.2.4, & 8.4.13.

6.1.5.2 G.MATH.1 – Mathematical Operations and Results

Evidence is required to support this goal that shows that mathematical operations and results are

valid. [BSI03] adequately defines the C++ mathematical model. Ambiguities in operator precedence

levels are known (Appendix 8 – 14) and can be avoided. Of particular interest are the appropriate

detection and handling of divide-by-zero and other similar errors. Detection of these activities can

be achieved through appropriate design and application of defensive programming techniques

(G1.1A.1.2B.2A.1 – defensive programming goal) or assertion checking (G1.1A.1.2B.2A.2). C++

also supports linking the manual detection of such cases to the exception handling mechanism. The

following rules and guidelines also support a rigorous mathematical model: Rules 5.2, 5.3, 10.17

and Guideline 10.18.

6.1.5.3 G.PARADIGM.1 – Paradigm Related Errors

Evidence is required to support this goal that shows that C++’s mechanics of the object-oriented

paradigm does not introduce errors into the design. The following rules and guidelines provide

restrictions to eliminate paradigm related errors and also promote conformance to the OOTiA

recommendations: Rule 3.1.3 – 3.1.8, 3.1.13, 3.2.1 – 3.2.3, 3.3.1 – 3.3.3, 3.3.5 – 3.3.15, 3.4.1 –

Page 78: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

71

3.4.6, 3.5.1 – 3.5.3, 8.3.3, 8.4.3, 8.4.11, 11.4, 11.5, 11.8, 11.9, 12.1, 16.3, 17.5, 4, 5, & 9 and

Guidelines 3.1.7, 3.1.9, 3.2.4, 3.4.7, 3.5.5, & 16.4

6.1.5.4 G.MISTAKES.1 – Unintentional Mistakes and Typos

Evidence is required to support this goal that shows that unintentional mistakes and typos are

prevented. C++ has traditionally been criticised that the lexically similar nature of many of its

constructs means that a single incorrect character can result in grammatically parsable code.

Development environments that utilise control structure diagrams (CSD) provide a graphical means

of detection many of these problems. Most C++ development environments support features such as

these. CSD is an algorithmic level diagram intended to improve the comprehensibility of source

code by clearly depicting control constructs, control paths, and the overall structure of each program

unit. CSD is particularly efficient at highlighting incorrect use of blocks and brackets and braces. It

also colour-codes keywords, variables, and literals to allow the programmer to visually detect

programming errors as they type. Coding style can also be used to prevent such errors. The

following rules and guidelines support the detection of unintentional mistakes and typos: Rules 6.1,

6.2, 10.5 – 10.6, 10.21, 14.5, 14.12 – 14.15, 14.17 – 14.18, 17.13 – 17.15, 17.17, 1, & 26 and

Guidelines 14.7, 17.21, 21, 23.

6.1.5.5 G.SIDE_EFFECT.1 – Side Effects in Expression

Evidence is required to support this goal that shows that side effects in expressions are intended.

Appendix 8 – 14 identifies side effects in expression for which [BSI03] is ambiguous. These are

known and can be avoided. The following rules and guidelines support the elimination of side

effects in expression: Rule 3.1.6, 3.5.1, 10.3 – 10.6, 10.8 – 10.10, 16.2, & 17.17 and Guideline 10.7.

6.1.5.6 G.JUMPS.1 – Modular and Structured Approach / Jump Restrictions

Evidence is required to support this goal that shows that C++ is modular and structured, and that

jumps between scopes are restricted. C++ supports functions, objects, separate compilation and

defines scoping properties associated with each of these structures to promote modularity. Although

C++ supports numerous unrestricted scope jumping mechanisms, the following rules place

restrictions on jumps between scopes and also promote the correct use of modularity: Rule 5.1, 5.4

– 5.6, 5.8, 5.9, 5.11, 5.12, 11.2.

6.1.5.7 G.MEMORY.1 – Memory Leaks

Evidence is required to support this goal that shows that opportunities for memory leaks in C++ are

restricted. The manual dynamic allocation/deallocation features of C++ make the language prone to

memory leaks. The following rules and guidelines place restrictions of memory and resource

activities to prevent memory leaks: Rules 3.1.3, 3.1.5, 3.2.5, 12.2 – 12.8, 17.9, 15, 17 & 25 and

Guidelines 9.5, 9.6, 16, & 22.

6.1.6 Avoiding, Mitigating, Detecting and Handling Goals – Figure 16-4

6.1.6.1 G1.1A.1.2B.2A.1 – Defensive Programming

Evidence is required to support this goal that shows that C++ supports defensive programming

techniques. C++ provides support for many common defensive programming techniques. These

may be dealt with through traditional conditional statements, or through linkage to the C++

exception handling mechanism. Preference would be for the latter. Rule 10.17 and Guideline 10.18

also support defensive programming. Local coding standards and design practices should promote

defensive programming techniques.

Page 79: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

72

6.1.6.2 G1.1A.1.2B.2A.2 – Assertions

Evidence is required to support this goal that shows that C++ supports the use of assertions. C++

permits various forms of assertion checking. Assertions can be hard coded into the actual software

and coupled with the run-time exception mechanism. Alternatively the <cassert> library provides

the assert macro. There are some limitations to using the assert macro and these are addressed by

the Rule 10.17.

6.1.6.3 G1.1A.1.2B.2B.1 – Design Patterns

[Gam95] presents designs patterns for object oriented software. Many of these patterns are

presented in C++. Reference to the existence of these patterns and their use as part of the system

design would be suitable to support this goal. It is important to highlight that the patterns have not

been verified with respect to the safer C++ subset and would require some validation work. There is

scope for a catalogue of safer C++ subset validated design patterns to be created.

6.1.6.4 G1.1A.1.2B.2B.2 – Code Reuse

Evidence is required to support this goal that shows that C++ supports the reuse of existing code.

C++ promotes code reuse through its mechanisms for separate compilation, standard library,

templates, objects, inheritance, and linkages with other languages to name a few. Rule 17.2

emphasises that the C++ standard libraries should be used in preference to hand coded versions

where possible.

6.1.6.5 G1.1A.1.2B.3 – Exception Detection and Handling

Evidence is required to support this goal that shows that C++ has an exception detection and

handling mechanism. C++ provides an exception handling system whereby exceptions are thrown

by type and not value. The following rules and guidelines places restrictions on the exception

handling system to make it robust: Rules 9.1 – 9.3, 11 – 13 and Guidelines 9.4 – 9.6,

6.1.7 Static Analysis Goals – Figure 16-10

6.1.7.1 G1.1A.2A.1A.1 – Dynamic Variables

C++ supports the use of both static and dynamic variables and objects. It is up to a design to restrict

the use of dynamic variables to those areas of the software where they are necessary. In situations

where they are used the limits of static analysis are to be specifically noted and the deficiency

deliberately addressed through dynamic testing.

6.1.7.2 G1.1A.2A.1A.2 – Interrupts

C++ support the use of interrupts. It is up to a design to restrict the use of interrupts to those areas

of the software design where they are necessary. In situations where they are used the limits of

static analysis are to be specifically noted and the deficiency deliberately addressed through

dynamic testing.

6.1.7.3 G1.1A.2A.1A.3 – Recursion

C++ supports recursion. It is up to a design to restrict the use of interrupts to those areas of the

software design where they are necessary. In situations where they are used the limits of static

analysis are to be specifically noted and the deficiency deliberately addressed through dynamic

testing. Rule 6 and Guideline 6.6 restrict the use of recursion to allow this goal to be satisfied.

6.1.7.4 G1.1A.2A.1B.1 – Resource Usage Behaviour

Evidence is required to support this goal that shows that aspects of C++ resource usage behaviour

are statically analysable. The use of dynamic objects in C++ makes this difficult to carry out for

Page 80: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

73

those portions of the design. QA C++ and MALPAS static analysis can be used to infer some

properties about C++ resource usage. The deficiencies in meeting this goal shall be addressed

through the dynamic resource usage behaviour goal (G1.1A.2A.2A.2).

6.1.7.5 G1.1A.2A.1B.2 – Temporal Behaviour

Evidence is required to support this goal that shows that aspects of C++ temporal behaviour are

statically analysable. QA C++ and MALPAS static analysis can be used to infer some properties

about C++ timing behaviour. The deficiencies in meeting this goal shall be addressed through the

dynamic timing behaviour goal (G1.1A.2A.2A.1).

6.1.7.6 G1.1A.2A.1B.3.1 – Control, Data and Information Flow

Evidence is required to support this goal that shows that aspects of C++’s function behaviour are

analysable through control, data and information flow analysis. MALPAS is capable of providing

static control, data and information flow analysis. The value tracking features of PC-Lint also

provide some limited capability in support of this goal.

6.1.7.7 G1.1A.2A.1B.3.2 – Assertions / Annotations

Evidence is required to support this goal that shows that aspects of C++’s function behaviour are

analysable through static assertion and annotation checking. Although not specifically a C++ tool,

MALPAS can be used to check pre-conditions, post-conditions and function invariants against the

interface definitions.

6.1.7.8 G1.1A.2A.1B.3.3 – Formal Code Verification

Evidence is required to support this goal that shows that aspects of C++’s function behaviour are

analysable through formal code verification. Although not specifically a C++ tool, MALPAS can be

used to provide formal code verification. Alternatively, generic object oriented mapping can be

used to permit the manual application of formal methods to C++ code.

6.1.7.9 G1.1A.2A.1B.3.4 – Symbolic Execution

Evidence is required to support this goal that shows that aspects of C++’s functional behaviour are

analysable through symbolic execution. Most C++ development environments provide a host a

debugging tools that are capable of symbolic execution of C++ source code. One of C++’s strengths

is the availability of debugging tools. These tools are dependent on the platform and environment.

6.1.7.10 G1.1A.2A.1C - Standards

IEC 61508, Defence Standard 00-55 and RTCA/DO-178B all specify requirements for static

analysis. Those standards that are applicable to the given project shall be identified. MALPAS is

recognised as providing the full range of static analysis techniques mandated in Defence Standard

00-55, IEC 61508 and RTCA/DO-178B. QA C++ has not been officially validated to Defence

Standard 00-55 [Coo04]. PC-Lint / FlexeLint has not been associated with these types of standards

to date.

6.1.8 Dynamic Testing Goals – Figure 16-11

6.1.8.1 G1.1A.2A.2A.1, G1.1A.2A.2A.2, and G1.1A.2A.2A.3 – Temporal / Resource /Functional

Tools such as Cantata++ can be used to dynamically test the temporal, run-time resource and

functional behaviour of programs developed in C++. Many other tools also exist to support such

testing activities in C++, although they have not been specifically identified or examined in this

Page 81: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

74

project. It is believed that Cantata++ is capable of addressing the deficiencies in static resource

usage and timing behaviours analysis.

6.1.8.2 G1.1A.2A.2B - Standards

[IPL03] states that “Cantata++ can be used to enable a software development to meet many of the

verification and testing requirements of IEC 61508.” The safety critical development standards used

also included consideration of those used for the European Fighter Aircraft, and Defence Standards

00-55 and 00-56.

6.1.9 Error Prevention Feature Goals – Figure 16-3

6.1.9.1 G1.1A.2B.1 – Complexity

Evidence is required to support this goal that unnecessarily complex portions of code are identified.

QA C++ and Cantata++ provide a means of assessing C++ code complexity through the reporting

of various software code metrics. Rules 4.1 – 4.3 limit the complexity of the source code and thus

also support this goal.

6.1.9.2 G1.1A.2B.2 – Abstraction and Information Hiding

Evidence is required to support this goal that C++ supports abstraction and information hiding

features to assign with error detection. The object oriented paradigm implemented by C++ supports

abstraction and information hiding. Separate compilation of C++ translation units promotes the

detection of errors within individual translation units.

6.1.10 Implementation Features Goals – Figure 16-1

6.1.10.1 G1.1B – Interfacing to Other Languages

C++ supports interfacing to other languages, however the behaviour associated with such

functionality is implementation defined. 1.6 in [PRG03] states “the embedding of code, written in

languages other than C++, within C++ is forbidden unless accompanied by a written justification

for its use.” In addition, Guideline 18 recommends that interfaces to language other than C be

avoided anyway.

6.1.11 Maintainability Goals – Figure 16-1

6.1.11.1 G1.2.1 – User Documentation and Comments

C++ provides two notations in which comments can be embedded within the source code. Rule 14.1

prohibits the use of the C style comments. C++ style comments are wholly suitable for comments

embedded within the code and this supports the instantiation of this goal. Further evidence would be

required to show that coding and design practices support appropriate documentation of the

implementation. QA C++ provides a means of generating class hierarchy diagrams and function call

diagrams in support of this.

6.1.11.2 G1.2.2 – Coding Style Guidelines

Projects should define a set of coding style guidelines that addresses issues such as layout, naming

conventions, local environment restrictions, etc. QA C++ can be configured and using post-analysis

it is possible to apply a high degree of automatic enforcement to a company coding standard

(company-specific rules such as a naming convention). The following rules and guidelines also

work to improve readability and maintainability:. Rules 2.1, 3.1.1, 3.3.16, 8.4.1, 8.4.4, 8.4.6, 8.4.7,

10.1, 10.19 – 10.20, 11.1, 11.3, & 15.3 and Guidelines 3.1.12, 6.6, 8.3.2, 8.4.12, 14.2 – 14.4.

Page 82: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

75

6.1.12 Development Team Expertise Goal – Figure 16-1

6.1.12.1 G2.1.1 – Development Team Expertise / Programmer Experience

This goal can only be satisfied through explicit reference to the people employed within the

development team for the project. Programmers should have a full appreciation of the safety

considerations associated with writing software in C++. One means of achieving this would to

ensure programmers are familiarised with the work presented in the entirety of this report.

Furthermore, a demonstrated appreciation of many of the texts referenced in the reference section of

this report would be useful evidence.

6.1.13 Tool Quality, Validation and Certification Goal – Figure 16-1

6.1.13.1 G3.1.1 – Tool Quality, Validation and Certification

Evidence is required to show that the tools cited in satisfying the other goals within the GSN pattern

are of a high quality, validated or certified. The following paragraphs identify those tool quality,

validation and certification issues that are known about the tools that may work towards supporting

this goal. Other tools related to context specific development environments shall also be considered

in support this goal.

• The Programming Research Group uses the Perennial Test Suit for checking the ISO C++

conformance of the QA C++ parser and the Boost library (version 1.3 for QA C++ 2.0) for

C++ parsing [Coo04]. The Programming Research Group have a coding standard in place

which is enforced with QA C++ itself [Coo04]. They believe that this puts them at Capability

Maturity Model Level 2, however they have not sought formal assessment yet. QA C++ has

not been officially validated to Defence Standard 00-55 [Coo04]. HICPP Coding Standard has

been given the tick in the box by TUV Germany [Coo04].

• Gimpel Software is not certified by any outside organisations. The following passage is

quoted directly from [Gim04] and relates to the quality of released versions of PC-Lint /

FlexeLint.

“We also employ extensive quality assurance procedures. Before we release a new version of

PC-lint, we do thorough in-house testing of the software. This includes testing both PC-lint

functionality and options. We have a standard test suite that we use in-house. We have a beta

testing period of at least six months, during which the product is tested by both current users

and new users. Finally, we have a large customer base and an active online discussion forum

to ensure a low incidence of miscellaneous errors.”

• MALPAS is widely used in the security, aerospace, defence, nuclear power and transport

industries [ATC03]. It has been applied to safety, security, mission and business critical

applications [ATC03].

• Cantata++ has been produced under IPL’s rigorous ISO9001TickIT Quality Management

System [IPL98]. “The product is itself fully tested at the unit, task, and system level” [IPL98].

[IPL03] states that “Cantata++ can be used to enable a software development to meet many of

the verification and testing requirements of IEC 61508.” [IPL03] also states that “the tools

have been produced to a high standard, such that their use for dynamic testing will not

compromise the safety and integrity of the software being tested.” According to [IPL03],

Cantata++ is in widespread use. Formal methods were not used in the specification of

Cantata++ [IPL03]. The safety critical development standards used included consideration of

those used for the European Fighter Aircraft, and Defence Standards 00-55 and 00-56.

Page 83: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

76

6.1.14 Summary of Evaluation Findings

The evaluation has shown that it is possible to provide reasonable evidence in support of the

justification of programming language selection for C++. The safer C++ subset is critical to the

activity as are a number of these tools (QA C++, MALPAS, Cantata++). PC-Lint was less essential

to the process, but should probably be considered a useful diverse check to QA C++.

There were a number of rules and guidelines that didn’t directly support the goals in the pattern.

These goals related to improving efficiency and thus are not required to support safer C++

development. The rule and guidelines supporting efficiency are Rules 11.5, 11.8, 17.6, &17.19 and

Guidelines 5.7, 17.3 – 17.4, 17.10, & 17.18. Thus it is possible to assume that the justification of

programming language selection pattern is sufficient within the scope of the kind of attributes

required to make C++ safer.

There were not any specific goals that could not be supported. There were weaknesses in the

availability of C++ specific tools for supporting static analysis (particularly resource and timing

analysis). MALPAS does not yet have a C++ translator for it and as such the static analysis is going

to be a large task. QA C++ is in the early days of providing formal code verification features.

However these deficiencies could be addressed through appropriate dynamic testing using

Cantata++. Exposure of QA C++ and PC-Lint to some of the standards covered in this thesis has

been limited to date.

Because there was no specific design context against which to carry out this evaluation, a number of

goals still required further investigation into their instantiation. Section 6.3 outlines approaches as

to how such evaluations might be conducted.

6.2 Evaluation of Safer C++ Subset Against Safe Language Criteria

This section examines the safer C++ subset defined by the HICPP coding standard and the

additional rules defined in Section 4.2. For comparison purposes, each mandatory criteria has been

rated using the specific rating definitions presented in [Kwo03]. The ratings in [Kwo03] are on a

scale of Rating 1 (best, safest) to Rating 3 (poorest). Subsections are annotated with an (M) or (D)

to represent mandatory and desirable requirements. Desirable criteria were not numerically rated in

[Kwo03] and as such they shall not be rated here either. Much of the information presented here is a

reflection of the information presented in the previous section. The duplication of information is

worthwhile as it serves as confirmation of the relationship between the safe language criteria and

the GSN pattern developed in Section 5.

6.2.1 Syntactical / Semantic Requirements (M)

6.2.1.1 Type Safety / Strong Typing Rules

C++ is a relatively, strongly typed language. However the flexibility of some features actually work

against type safety. Implicit conversions are not allowed for Plain Old Data (POD) (ie. primitive)

types. However, C++ permits implicit conversions between objects of class type. There is also

potential for a less experienced programmer to inadvertently enact these implicit conversions. The

use of the HICPP coding standard places restrictions to prevent implicit type conversions occurring.

C++ provides a number of explicit type conversion mechanisms that are defined in the C++

standard. The use of the HICPP coding standard places restrictions on the use of these conversions

to improve type safety.

C++ arrays lack array bounds checking and enforcement. Overloading operator[] with index range

checking improves the safety of arrays. Making classes of scalers and overloading the assignment

operator allows additional range and value checking. The use of vector and deque rather than the

Page 84: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

77

base language array primitive helps to enforce array bounds checking. However there is some doubt

as to whether certain implementations of these types are statically analysable. Many of the container

types defined in the STL perform their own dynamic allocation and deallocation and this may also

prevent them being statically analysed.

C++ provides both pointer and reference access types. The programmer is not forced to use such

types. However, much of the STL and many of the most useful features of objects and classes

utilise these access types. These types present challenges to the static analysis of software. Software

designers and programmers should limit the use of these types to those aspects of the design where

their use is necessary and justifiable.

C++ supports multiple inheritance and conversions up and down the inheritance hierarchy. The use

of the HICPP coding standard places restrictions to prevent type slicing and other inheritance

related problems occurring.

Rating: 2. Strongly typed, but some types are analysable only at run-time.

The development of a design that avoids aspects of the types that are analysable only at run-time

could be given Rating: 1. Strongly typed, statically analysable.

6.2.1.2 Side Effects In Expressions / Operator Precedence Levels / Initial Values

Side effects in expression can occur with numerous C++ language features. The C++ standard

explicitly annotates if such side effects are defined or at the discretion of the compiler

implementors. The operator precedence levels are also defined in the C++ standard, but they are not

always intuitive to the programmer. C++ provides means of default initialising certain types and

also implicitly initialises certain types. The use of the HICPP coding standard and the additional

rules defined in Section 4.2 places restrictions on these aspects of the language and ensures that the

code is not impacted due to unfounded assumptions about expression side effects, operator

precedence levels and initial values.

Rating: 1. All of the specifics are satisfied.

6.2.1.3 Modularity / Structures

In C++, programs can be organised as objects that consists of data and the functions that operate on

that data. Such language features promote modularity and structured programming. Abstract classes

can be used to define semantically clear interfaces and provide relative separation of interface from

implementation. The correct use of classes to facilitate abstraction and encapsulation also promotes

modular and structured programming. Access to members (data and functions) can be controlled

with the use of access specifiers (public, protected and private). Separate compilation is also

possible.

Blocks and scopes are well defined by the C++ standard. However, C++ does provide some

mechanisms that allow wild or unbounded jumps between scopes. The use of the HICPP coding

standard and the additional rules defined in Section 4.2 places restrictions on these aspects of the

language. C++ also provides numerous language features for controlling the program flow,

including standard conditional control structures (eg. if, else, while, & switch) and an exception

handling mechanism.

Rating: 1. The language provides rich and precise means of structuring programs, and programs can

be maintained in terms of modules and objects.

Page 85: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

78

6.2.1.4 Formal Semantics / International Standards

C++ was ANSI / ISO Standardised in 1998 [BSI03]. The standard formally defines the semantics of

the language. It also defines those parts of the language that are unspecified, undefined,

implementation-defined, and indeterminate. The use of the HICPP coding standard and the new

rules proposed in Section 4.2 control the unspecified, undefined, implementation-defined, and

indeterminate behaviours.

Rating: 1. An internationally standardised formal definition exists.

6.2.1.5 Well Understood

Section 2.1.5 identified the wide availability of published textbooks relating to the development of

software in C++. Specifically a number of textbooks were identified that identify C++ best practice,

problems and solutions. These books are widely referenced by the C++ community. There is

substantial agreement on problems and solutions between these texts and this supports the notion

that C++ is well understood.

C++ is widely taught in educational institutions. C++ is also widely used in numerous commercial

and industrial sectors. C++ has seen some use in the military domain also.

While only a number of tools have been considered throughout this project, a large number of

development and support tools are available for many aspects of C++ development. There are some

deficiencies in the availability of formal proof tools for C++.

Rating: 1. The language is well understood, and there are many trained developers and designers.

6.2.1.6 Support For Domain Specific or Embedded Applications

In Section 2.1, C++ was described as a middle level language as it combines the best aspects of

high level languages, while still allowing the programmer the control and flexibility of assembly

language. For this reason, C++ has been widely used as a systems programming language. Thus the

language naturally supports embedded applications. Many hardware manufacturers provide C or

C++ interface libraries with their processors and development packages. C++ programs can be

linked seamlessly with C modules where required. A number of modelling packages can also

automatically generate C++ code from high-level mathematical models for compilation on an

embedded system.

C++ provides a large number of language constructs and features that permit the language to be

successfully applied to a broad range of applications. Care must be taken to ensure the correct

language features are applied to the solution as it is possible to produce a poor (and potentially

unsafe) program if language features are used out of context.

Rating: 1. The language naturally supports embedded applications.

6.2.1.7 Concurreny / Parallel Processing

The C++ standard (base language and STL) does not define any high level concurrency or multi-

threaded features. C++ does provide an exception handling mechanism, however this still exists

within a single thread of execution. Some of the low level features of C++ allows access to

interrupts and thus the programmer is free to develop their own concurrency support. In addition

numerous commercial libraries are available that provide support for concurrency. However these

are unlikely to have been validated with respect to any particular safety criteria.

Rating: 2. Only limited support is provided at the language-level, but external libraries or run-time

systems can be utilised.

Page 86: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

79

6.2.2 Application of Verification Techniques / Predicability (M)

6.2.2.1 Functional Predicability

Numerous tools are available for C++ that support control, data, and information flow analysis. For

example QA C++ and PC-Lint / FlexeLint both provide some support for these techniques. C++

debugging tools that support symbolic execution are also widely available with most development

environments. Some tools, such as MALPAS, are available that support formal code verification,

however direct input of C++ code into such tools is not yet supported. For example MALPAS does

not presently provide an automatic translation mechanism for translating C++ into the MALPAS

intermediate language. This does not prevent manual translation of C++ code into the MALPAS

intermediate language, though this will be time consuming.

Rating: 1. All techniques specified or feasible alternatives can be utilised.

6.2.2.2 Temporal Predicability / Timing Analysis

It is possible to determine tightly bounded execution times for C++ code. C++ was developed to

allow highly efficient execution of C++ code with minimal run-time overheads. C++’s single

threaded execution and manual memory management features avoids problems associated with

determining execution times for multi-threaded applications and garbage collectors. While the

implementation of many of the features of the STL are not presented to the user, it is possible to

establish accurate worst case execution times for these functions.

Rating: 1. Tightly bounded execution times can be obtained.

6.2.2.3 Resource Usage Analysis

C++ supports both stack (global, local, static / non-static) and heap based allocation of memory.

There are some ambiguities associated with static allocation across translation units in C++.

However the use of the HICPP coding standard and the additional rules defined in Section 4.2

places restrictions to prevent such situations. Thus finite resource usage analysis is possible for C++

stack based memory allocation.

Dynamic memory allocation is traditionally difficult to analyse. However through the use of the

HICPP coding standard and the additional rules defined in Section 4.2 controls and safeguards can

be placed on the dynamic allocation and deallocation of memory such that out of memory or low

resource situations can be dealt with safely. Numerous tools are also available to help analyse and

test dynamic memory allocation in C++.

Rating: 1. Exact predicability of the specifics is possible.

6.2.3 Language Processors / Run-Time Environment Tools (M)

6.2.3.1 Certified Language Translators / Run-Time Environments

Numerous software bodies offer compiler certification services for C++ compilers. Compilers that

are certified against the C++ standard are becoming more widely available. However many

commonly available compilers also support their own customisations to the C++ standard.

Compilers developed prior to C++ standardisation often contain varying interpretations of C++

language and STL features. These should not be used. In addition there is much scope still for C++

compilers to be formally verified. The wide use of C++ compilers helps to provide confidence from

use. Intelligently applied dynamic testing can work to provide confidence that bugs are not

introduced by the compiler.

Page 87: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

80

Many C++ development environments and tools are widely available. They are also widely used

and thus it is possible to argue increased confidence from use.

Rating: 2. Language translators may contain several known errors or malfunctions that are well

documented, but they will not affect the development of high integrity software.

6.2.3.2 Run-Time Support / Environment Issues

In the interest of execution efficiency, C++ only provides a minimal run-time overhead. Thus the

impact on functional and timing analysis is minimal. The functionality of the STL is defined by the

C++ standard. While the implementation of many of the features of the STL are not presented to the

user, it is possible to establish accurate execution times for these functions through testing.

Rating: 1. There is concrete information on the functional and temporal behaviours of all libraries

and run-time system.

6.2.4 Syntactical / Semantic Requirements (D)

6.2.4.1 Exception Handling / Failure Behaviour

C++ provides a built-in exception handling mechanism. C++ extends the exception handling

capabilities beyond that of other languages as C++ exceptions are handled by type rather than value.

Thus it is possible to create hierarchies of exception classes and catch the exception by thrown

subclass type. Uncaught exceptions can become problematic as they may result in the program

terminating. The HICPP coding standard and additional rules defined in Section 4.2 place

restrictions on the use of exceptions and exception class design in order to promote predictable

exception and failure behaviour.

6.2.4.2 Model of Mathematics

C++ provides a well defined set of integer and floating point data types. The use of the HICPP

coding standard and the additional rules defined in Section 4.2 ensures the type safety of these data

types. They also promote the correct use of mathematical operations associated with these types.

In addition the STL also provides more complex mathematical structures and operations including

complex numbers through its numerics libraries. While there are numerous unspecified, undefined

and implementation-defined behaviours associated with some of these types, they can be controlled

through the use of the HICPP coding standard and the additional rules defined in Section 4.2.

6.2.4.3 Support for User Documentation

C++ supports both C and C++ style comments. The C style comments are banned in HICPP, but the

C++ comments are ample for fully documenting the source code. In addition, some C++ tools, such

as PC-Lint / FlexeLint, use commands embedded within C++ style comments to control the tool’s

analysis of the source code.

6.2.4.4 Support For A Range Of Static Types Including Subtypes and Enumeration Types

C++ supports enumeration types. Subtypes of POD types can be emulated with additional overhead.

Subtyping of class types is supported in C++ through inheritance. The use of the HICPP coding

standard and the additional rules defined in Section 4.2 ensures the safety of these data types.

6.2.4.5 Coding Style Guidelines

The HICPP coding standard and the additional rules defined in Section 4.2 not only subset the C++

language, they also offer rules and guidelines relating to producing documented, readable and

Page 88: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

81

maintainable code. In addition, further guidance on producing readable and maintainable code is

presented is several of the texts examined in Section 2.1.5.

6.2.4.6 Support For Abstraction and Information Hiding

C++’s implementation of the object-oriented paradigm supports abstraction through templates,

inheritance, and abstract classes (with virtual members). C++ also provides access specifiers

(public, protected and private) to allow information hiding within objects.

6.2.4.7 Assertion Checking

C++ permits various forms of assertion checking. Assertions can be hard coded into the actual

software and coupled with the run-time exception mechanism. Alternatively the <cassert> library

provides the assert macro. There are some limitations to using the assert macro and these are

addressed by the HICPP coding standard.

Although not specifically a C++ tool, MALPAS can be used to check pre-conditions, post-

conditions and function invariants against the interface definitions.

6.2.5 Language Processors / Run-Time Environment Tools (D)

6.2.5.1 Certified (Static/Dynamic) Analysis Tools

A large number of analysis tools have been developed to assist in debugging and analysing C++

programs. However, most of them are not certified by reliable bodies or standards. A number of

standards also permit the use of tools where increased confidence from previous use has been

established. Section 6.1.13 examined the quality of QA C++, PC-Lint / FlexeLint, Cantata++ and

MALPAS.

6.2.5.2 Interface To Other Languages

C++ provides many features for interfacing to other programming languages. However many of

these features are specific to the platform or implementation. The HICPP coding standard and the

additional rules defined in Section 4.2 place restrictions on the use of interfacing C++ code to other

languages to limit the external language interface mechanics that are unspecified or

implementation-defined. This results in recommending avoiding linkage to languages other than C.

6.2.5.3 Code Optimisation

Many C++ compilers apply optimisation techniques to the code they are translating. In many cases

the C++ standard leaves the creation of temporary objects and optimisations to the compiler

implementors. It is complex to statically analyse optimised machine code in relation to high level

source code. Some compilers provide means of turning off the optimisations. However even with

optimisations turned off a small number of optimisations will still be applied during compilation.

Optimisation makes the compiler and tool validation complex and difficult.

6.2.5.4 Code Portability

The C++ programming language is designed to be a portable language. However, an inspection of

the C++ standard [BSI03] reveals a large number of unspecified or implementation-defined

behaviours. Appendixes 8 to 14 list in detail these behaviours. The HICPP coding standard and the

additional rules defined in Section 4.2 place sufficient restrictions on these behaviours to ensure

portability.

Page 89: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

82

6.2.6 Summary and Comparison with Other Languages

Within the mandatory criteria the safer C++ subset was assessed to be of the best rating (Rating 1)

for all except for three criteria that received Rating 2. The first two relate to type safety and to

concurrency. These two criteria can be controlled through the system design and can thus

conceptually achieve a Rating 1 for specific designs. The third criteria relates to certified language

translators. Compilers that are certified against the C++ standard are becoming more widely

available. In addition, C++ compilers are generally no less certified than the bulk of other language

translators available.

C++ was also assessed favourably across the desirable criteria. While some weaknesses were

identified, there are practical means of avoiding or preventing them.

C++ rated substantially better as a safe language than did Java as evaluated by [Kwo03]. A

worthwhile activity would be to also evaluate Ada and SPARK using the same system. Thus it

would be possible to establish a common baseline comparison of programming languages for high

integrity systems. The evaluation may also be applied to numerous other language subsets.

6.3 Proposal for Evaluating the GSN Argument

Section 5.1 described the development of a pattern for arguing the selection of a programming

language for a safety critical system. The pattern is presented in Appendix 16. Section 6.3.1 details

a proposal for evaluating the correctness and applicability of the pattern.

Section 6.1 described the evaluation of the pattern developed in Section 5.1 for the C++

programming language. Section 6.3.2 details a proposal for evaluating the finding of Section 6.1 as

it is applied to a project.

Both evaluations are presented as proposals since there was insufficient time during the project to

actually carry out the evaluations. This should not detract from their importance in establishing C++

as a safety critical programming language. Both of the proposals should be considered a high

priority in future work.

6.3.1 Proposal for Evaluating the Pattern Against Existing Software Safety Cases

A number of existing software safety cases should be assembled along with their relevant design

documentation. Ideally safety cases should be selected such that a cross section of commonly used

programming languages are subject to the evaluation. For example a set of projects developed in

Ada, SPARK, and C would be a suitable cross section. It is unlikely at this time that there are many

safety cases available for systems involving the use of C++. However if such safety cases can be

obtained, then their inclusion should be mandatory.

The essence of the evaluation is to attempt to instantiate the pattern from the evidence already

available in an existing software safety case and associated design documentation. This provides the

opportunity to examine the following questions:

• Has the existing safety case appropriately justified the programming language selection, even

if they haven’t specifically argued it?

• Are there deficiencies in the existing safety case where this pattern suggests that additional

evidence should be assembled? Furthermore does this pattern help to identify where the

language selection for an existing system is inappropriate or unjustifiable?

Page 90: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

83

• Is there evidence and goals suggested by the existing safety case that are not covered by the

pattern? What are they, should they be included in the pattern, and how could the pattern be

reworked to include them?

• Are there issues that might prevent this pattern being instantiated that may require the pattern

to be reworked? In particular what aspects of the pattern are not lending themselves to

instantiation? How might the pattern be reworked? How could the reworked pattern be

validated?

• Are there techniques and tools not used in justifying the language selection that that would

have improved the justification?

• Are there techniques and tools used in justifying the language selection that are not

compatible with the pattern in its present form?

There is a substantial amount of work involved in conducting this evaluation.

6.3.2 Proposal for Evaluating the Pattern on C++ Projects

A series of real world engineering projects shall be identified where the C++ programming

language suits the domain and application. The projects shall also be safety critical. The risks

presented by conducting the evaluation first time around on a very high risk project are probably

significant. Discussions with industry have revealed that some companies have begun developing

software in C++ for safety critical projects with a low inherent risk. Thus an ideal starting point for

this evaluation would be on a project of similarly low risk. Subsequent to establishing confidence at

this level of criticality, then the same evaluation should be applied iteratively to a future series of

projects with a goal of gradually increasing safety criticality. The goal is to eventually evaluate one

or more projects of substantial safety criticality.

The software shall be developed using the language subset, tools, techniques and processes

described by the evaluation presented in Section 6.1. Applicable safety standards shall be defined

for the project, but at the very least these should include a subset of IEC61508, DO178B, Defence

Standard 00-55 Issue 2 and Defence Standard 00-56 Issues 3.

The essence of the evaluation is to attempt to fully instantiate the pattern throughout development

of the safety case for the project. This provides the opportunity to examine the following questions:

• Can the use of C++ be justified for the project? Can this justification be successfully argued

using a full instantiation of the partially instantiated pattern? What additional evidence is

required to fully instantiate the argument?

• Are deficiencies emerging in the project where the instantiation of this pattern suggests that

additional evidence should be assembled? Furthermore does this partial instantiation help to

identify where the C++ language selection is inappropriate or unjustifiable?

• Are there issues that might prevent the argument being fully instantiated that may require the

underlying pattern to be reworked? In particular what aspects of the argument are not lending

themselves to instantiation? How might the instantiation and pattern be reworked? How could

the reworked instantiation and pattern be validated?

• Was the enforcement of the HICPP coding standard and the additional rules and guidelines

presented in Section 4.2 practical in the context of the project? Was the level of auto-

enforcement sufficient?

Page 91: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

84

• How well did the design translate into C++ and were methods or techniques identified that

assisted with the translation of design into source code? Was there scope for validated design

patterns to improve the safety of the design in the context of the application and domain?

• Are there techniques and tools presented in the partial instantiation of the pattern that were not

compatible with the project?

• Are there techniques and tools used in justifying the language selection that have not been

instantiated in the partial instantiation so far? What are they?

• Does the tool set and techniques suggested by the partial instantiation make development in

C++ feasible, economical and safe?

It will be too late if answers to these questions are not sought until the conclusion of the project.

Thus, throughout each of the project milestones (conceptual, preliminary, critical design reviews,

etc.) an assessment shall be carried out to assess if the desired safety is actually being achieved.

This may be in the form of a risk assessment (risk being a function of severity and likelihood), a

hazard analysis, or other acceptable study, but should be compatible with the nature of the project.

The aim of such an assessment is to ensure problems are identified early while there still may be

time and resources to address the problem. In some cases the outcome may be that more tools or

checks are required with respect to the C++ language. Alternatively, a problem may be identified

that requires a different language to C++ to be used.

There is a substantial amount of work involved in conducting this evaluation. Such an evaluation

would require a close relationship with a number of industry projects and may present some level of

workload burden on these projects.

Page 92: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

85

7 Conclusions and Further Work

The aim of this project was to examine the use of the C++ programming language in the context of

safety critical systems. This project endeavoured to examine justifiable evidence relating to the use

of C++ in safety critical systems. This project has specifically sought answers to the following

questions.

• Can the C++ programming language be used for the development of safety critical systems?

• If the C++ programming language as a whole is not suitable for safety critical systems, then

can constraints and restrictions be placed on the language (ie. language sub-setting) to permit

its use? What would these constraints and restrictions be? Can they be appropriately defined?

Are they sufficient?

• What tools are currently available to support the development of safety critical software using

the C++ programming language? Do the tools support verification of the software’s safety?

• What do the applicable safety standards say and could C++ be justified within the context of

these standards? How could justification be achieved?

7.1 Findings and Traceability to the Project’s Aims

This section presents the projects findings in relation to the project’s aims. Each of the aims is listed

along with the relevant findings.

Can the C++ programming language be used for the development of safety critical systems?

Section 3 has identified behaviours and problems in C++ that make the unconstrained use of the

language unsuitable for use in safety critical systems. However, there are few languages that can be

used un-constrained in the safety critical domain, and thus there was cause to consider subsets of

the C++ programming language.

If the C++ programming language as a whole is not suitable for safety critical systems, then can

constraints and restrictions be placed on the language (ie. language sub-setting) to permit its use?

Because Section 3 has identified behaviours and problems in C++, it is possible to reason that these

behaviours and problems can be controlled. Section 4 conducted a complete assessment of all

known behaviours and problems with respect to their constrainability. In doing this Section 4

identifies that it is important to match the programming language to the design, domain and

application. Of particular note, object-oriented design patterns have been identified as one means of

addressing such an issue.

What would these constraints and restrictions be? Can they be appropriately defined? Are they

sufficient?

Section 3 identifies the High Integrity C++ (HICPP) Coding Standard as a suitable starting point

for defining these constraints and restrictions, and thus developing a safer C++ subset. Section 4

has evaluated HICPP against a comprehensive set of C++ behaviours and problems to determine

the extent of its coverage. Deficiencies have been identified and new rules developed to address

them. The enforcement of the safer C++ subset (HICPP and additionally defined rules and

guidelines) has also been examined and the subset is believed to be largely enforceable. There is

still some scope for QA C++ to provide improved enforcement of numerous rules and guidelines,

particularly those that are STL related.

Page 93: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

86

What tools are currently available to support the development of safety critical software using the

C++ programming language?

There are many C++ tools on the market today. To allow completion of the project within allocated

timeframe, the number of tools considered was restricted. Section 4 has identified QA C++, PC-Lint

/ FlexeLint, Cantata++ and MALPAS as tools suitable to support safety critical software

development using the C++ programming language. It is important to note that the certifiability of

these tools was only briefly examined and that future work is needed to ascertain this.

The project has also identified a few areas where improved tool support would better facilitate

safety critical software development in C++. Within the set of tools considered for this project,

there were weaknesses in the availability of C++ specific tools for supporting static analysis

(particularly resource and timing analysis). MALPAS does not yet have a C++ translator for it and

as such the static analysis is going to be large task. QA C++ is in the early days of providing formal

code verification features. However these deficiencies could be addressed through appropriate

dynamic testing using Cantata++. Exposure of QA C++ and PC-Lint to some of the standards

covered in this thesis has been limited to date.

Do the tools support verification of the software’s safety?

Section 5 has proposed a safety argument that could be used to argue the selection of programming

language for safety critical systems. A significant component of this argument has been to argue

that the language and tools supporting the language support the top-level claim. Successful support

of the top-level claim can be interpreted as an indication that the tools support verification of the

software’s safety.

What do the applicable safety standards say and could C++ be justified within the context of these

standards?

The programming language criteria have been identified in Section 2.3 of this report. The main

point to be derived from the criteria is that the language selection needs to be justified within the

context of the safety critical system to which it is being employed. In addition, any prescriptive

elements of these standards with regards to language selection have been incorporated into a means

of justifying programming language selection (Section 5.1). The pattern has also been kept flexible

to permit justification of language criteria under other standards.

How could justification be achieved?

Section 5 has proposed a safety argument that could be used to argue the selection of programming

language for safety critical systems. The underlying argument has been constructed based on the

information contained in these standards, as well as other identified criteria associated with safe

language selection.

Section 6 has shown that it is possible to provide reasonable evidence in support of the justification

of programming language selection for C++. The safer C++ subset is critical to the activity as are a

number of these tools (QA C++, MALPAS, Cantata++). PC-Lint was less essential to the process,

but should probably be considered a useful diverse check to QA C++. Thus it is possible to assume

that the justification of programming language selection pattern is sufficient within the scope of the

kind of attributes required to make C++ safer.

In addition to the project’s aims, this project has also identified the most pertinent concerns in

relation to the use of the C++ programming language for safety critical systems (Section 2.6.2). In

seeking answers to the questions posed by this project, it is also believed that many of the

Page 94: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

87

perceptions and opinions have been addressed through the evaluation of the safer C++ subset

against the language criteria conducted in Section 6.2

This project has concluded that it is possible to use C++ to write software for use in high integrity

and safety critical applications. This may be achieved though the use of the safer C++ subset

(HICPP and additional rules) and a number of software tools for enforcement, static analysis and

dynamic testing. In conjunction, some degree of manual code reviews and design inspection are

also required. The project has also identified a few areas where improved tool support would better

facilitate safety critical software development in C++.

7.2 Further Work

While this project has shown that C++ can indeed be used for safety critical systems, it is immature

in the safety domain at this time. A number of activities are required in order to develop safety

maturity for C++ and these are as follows.

• C++ needs some further exposure to the safety critical environment at higher levels of

integrity.

• Further development is needed with respect to the auto-enforcement of the safer C++ subset.

(HICPP coding standard and additional rules defined in Section 4.2). The current rules and

guidelines are largely enforceable, but there are some significant deficiencies also. There is

also scope for different means of enforcement to be developed to assist with enforcing more

ambiguous rules.

• C++ tools should be identified or developed to address the identified tool deficiencies. This is

particularly important for some of the static analysis deficiencies.

• This project only examined the use of PC-Lint / Flexi-Lint for those areas where QA C++ was

identified not to provide full coverage. Thus a useful activity would be to conduct an audit of

PC-Lint / FlexeLint’s detection capabilities against all the items identified in this project.

Such an audit would provide a good indication on which areas PC-Lint can provide diverse

detection of problems.

• There is scope for existing object-oriented design patterns, and specifically those with

documented C++ implementations, to be validated with respect to the safer C++ subset. This

may be one means of providing developers with the right building blocks in which to

correctly implement a design.

• The justification of programming selection argument requires further evaluation. Two means

of performing this have been proposed in Section 6.3.

• Other languages, such as Ada and SPARK, should be evaluated against the safe language

criteria to establish a common baseline comparison of programming languages for high

integrity systems.

• The argument structures should be widely circulated to both the C++ and safety communities.

This will enable the work to be scrutinised and criticised such that an indication of the

industry’s acceptance can be gained.

Page 95: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

88

References

[ATC03] Advantange Technical Consulting, “MALPAS – Advanced Software Analysis and

Verification – Introductory Guide”, Surrey: Advantage Technical Consulting, 2003.

[Bar02] J. Barnes, B. Dobbing and R. Chapman, “On the Principled Design of Object Oriented

Programming Languages for High Integrity Systems”, Praxis Critical Systems Limited,

presented at the 2nd NASA/FAA Object Oriented Technology in Aviation Workshop,

2002.

[Bar03] J. Barnes, “High Integrity Software: The SPARK Approach to Safety and Security”,

Great Britain: Addison-Wesley, 2003.

[BSI03] British Standards Institute, “The C++ Standard: Incorporating Technical Corrigendum

1”, England: John Wiley & Sons, 2003.

[CAS04] Department of Computer Science, “CAS: Computers and Software & ISA”, Lecture

Notes, University of York, 2004.

[Cha04] R. Chapman, “MISRA C at SIL4? Perspectives and Alternatives”, Praxis Critical

Systems Limited, United Kingdom, March 2004.

[Coo04] Email: T. Coomber of Programming Research Group to D. Reinhardt, “RE: QAC++ and

Standards”, 9 August 2004.

[Cul91] W.J. Cullyer, S.J. Goodenough and B.A. Wichmann, “The choice of computer

languages for use in safety-critical systems”, published in the Software Engineering

Journal, March 1991.

[DDC04] DDC-I Inc., “Ada Helps Boeing Cut Cost On Commanche”, DDI-C Inc.,

http://www.ddci.com/programs_rah66.shtml, 2004, Accessed 09 July 2004.

[Dei94] H.M Deitel and P.J. Deitel, “C: How to Program”, Second Edition, New Jersey:

Prentice Hall, 1994.

[Dew03] S.C. Dewhurst, “C++ Gotchas: Avoiding Common Problems in Coding and Design”,

Boston: Addison-Wesley, 2003.

[Dou98] B.P. Douglass, “Safety-Critical Systems Design”, I-Logix, http://www-md.e-

technik.uni-rostock.de/ma/gol/ilogix/scritd.pdf, 1998, Accessed 07 June 2004.

[ECP04] The Embedded C++ Technical Committee, “The Embedded C++”,

http://www.caravan.net/ec2plus/, 2004, Accessed 04 September 2004.

[Gam95] E. Gamma, R. Helm, R. Johnson, J. Vlissides, “Design Patterns – Elements of Reusable

Object-Oriented Software”, Massachusetts: Addison-Wesley, 1995.

[Gim01] Gimpel Software, “Reference Manual for PC-Lint/FlexeLint”, Collegeville

USA:Gimpel Software, July 2001.

[Gim04] Email: A. Gimpel of Gimpel Software to D. Reinhardt, “Quality Assurance

Procedures”, 09 August 2004.

Page 96: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

89

[Hat95] L. Hatton, “Safer C: Developing Software for High-integrity and Safety-critical

Systems”, United Kingdom: McGraw-Hill, 1995.

[Hen97] M. Henricson and E. Nyquist, “Industrial Strength C++: Rules and Recommendations”,

New Jersey: Prentice Hall, 1997.

[HRM04] Department of Computer Science, “HRM: Hazard & Risk Management & Safety

Cases”, Lecture Notes, University of York, 2004.

[IEC98] International Electrotechnical Commission, “IEC 61508: Functional Safety of

Electrical/Electronic/Programmable Electronic Safety-Related Systems”, Switzerland,

1998.

[IPL03] IPL Information Processing Limited, “IPL Testing Tools and IEC 61508”, Bath: IPL

Information Processing Limited, 2003.

[IPL96] IPL Information Processing Limited, “An Introduction to Safety-Critical Systems”,

Bath: IPL Information Processing Limited, 01 August 1996.

[IPL98] IPL Information Processing Limited, “Cantata C++ - Technical Brief”, Bath: IPL

Information Processing Limited, 17 December 1998.

[Kwo03] J. Kwon, A. Wellings, and S. King, “Assessment of the Java Programming Language

for Use In High Integrity Systems”, University of York, ACM SIGPLAN Notices, April

2003.

[Law97] P.K. Lawlis, “Guidelines For Choosing A Computer Language: Support For The

Visionary Organization, 2nd Edition”, C.J. Kemp Systems Inc, August 1997.

[Lou93] K.C. Louden, “Programming Languages: Principles and Practice”, Boston: PWS

Publishing, 1993.

[Mey01] S. Meyers, “Effective STL: 50 Specific Ways to Improve Your Use of the Standard

Template Library”, Indianapolis: Addison-Wesley, 2001.

[Mey96] S. Meyers, “More Effective C++: 35 New Ways to Improve Your Programs and

Designs”, Indianapolis: Addison-Wesley, 1996.

[Mey98] S. Meyers, “Effective C++, Second Edition: 50 Specific Ways to Improve Your

Programs and Designs”, Indianapolis: Addison-Wesley, 1998.

[MIS98] The Motor Industry Software Reliability Association (MISRA), “Guidelines For The

Use Of The C Language In Vehicle Based Software”, Nuneaton: Motor Industry

Research Association, April 1998.

[MoD97] Ministry of Defence, “Defence Standard 00-55 Issue 2: Requirements for Safety Related

Software in Defence Equipment”, Great Britain, 1 August 1997.

[MoD04] Ministry of Defence, “Defence Standard 00-56 Issue 3 (Final Draft): Safety

Management Requirements for Defence Systems”, Great Britain, 30 January 2004.

[OOT04] Federal Aviation Administration (FAA), “Handbook for Object-Oriented Technology in

Aviation (OOTiA) – Draft vPC.0”, http://www.faa.gov/certification/aircraft/, 30

January 2004, Accessed 07 June 2004.

Page 97: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

90

[PRG03] The Programming Research Group, “High-Integrity C++ Coding Standard Manual:

Version 2.1”, http://www.programmingresearch.com, 24 October 2003.

[PRG04] The Programming Research Group, “QA C++ User Guide – Version 2.0”, The

Programming Research Group, 2004.

[Pri03] CS109 Lecture Notes, “Evolution of Programming Languages”,

http://www.cs.princeton.edu/courses/archive/fall03/cs109/lect06a.pdf, 2003, Accessed

07 June 2004.

[Row94] R. Rowe, “Safety Critical Systems Computer Language Survey Results”,

http://vl.fmnet.info/safety/lang-survey.html, 1994, Accessed: 07 June 2004.

[RTC92] RTCA Inc., “RTCA/DO-178B: Software Considerations in Airborne Systems and

Equipment Certification”, Washington D.C.: RTCA Inc., 1992.

[Sch03] H. Schildt, “C++: The Complete Reference”, Fourth Edition, Berkeley: McGraw-

Hill/Osborne, 2003.

[Sto96] N. Storey, “Safety Critical Computer Systems”, Great Britain: Prentice Hall, 1996.

[Str00] B. Stroustrup, “The C++ Programming Language”, Addison-Wesley, 2000.

[Sur04] D.G. Sureau, “History and Evolution of Programming Languages”,

http://www.scriptol.org/history.php, May 2004, Accessed 07 June 2004.

[Sut00] H. Sutter, “Exceptional C++: 47 Engineering Puzzles, Programming Problems, and

Solutions”, Indianapolis: Addison-Wesley, 2000.

[Wic98] B. Wichmann, “Moderated Discussion on C++ and Safety”, Safety Critical Mailing

List, http://www.cs.york.ac.uk/hise/sclist/cplussafety.html, 20 Mar 1998, Accessed: 07

June 2004.

[Ver03] A. Verkeyn, “History of Programming Languages”, Ghent University,

http://faramir.rug.ac.be/courses/soot1/dungeon/histlang.html, 23 October 2003,

Accessed: 01 June 2004.

Page 98: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1-1

Appendix 1 – HICPP Coverage of Industrial Strength C++ Items

The following table details the HICPP coverage of the items presented in Industrial Strength C++

[Hen97].

Industrial Strength C++ Item Control Enforced

Rec 1.1 Use meaningful names Maintenance

Rec 1.2 Use English names for identifiers Maintenance

Rec 1.3 Be consistent when naming functions, types, variables,

and constants.

Maintenance

Rec. 1.4 Only namespace should be global. Rule 8.2.2 (direct) QAC++

Rec 1.5 Do not use global using declarations and using directives

inside header files.

Guideline 8.2.3 (direct)

Guideline 8.2.4 (direct)

QAC++

QAC++

Rec 1.6 Prefixes should be used to group macros. Maintenance

Rec 1.7 Group related files by using a common prefix in the

filename.

Maintenance

Rule 1.8 Do not use identifiers that contain two or more

underscores in a row.

Maintenance

Rule 1.9 Do not use identifiers that begin with an underscore. Maintenance

Rule 2.1 Each header file should be self-contained. Guideline 8.1.1 (direct)

Guideline 8.1.2 direct)

Guideline 8.1.3 (direct)

QAC++

QAC++

QAC++

Rule 2.2 Avoid unnecessary inclusion. Guideline 8.1.1 (direct)

Guideline 8.1.2 (direct)

Guideline 8.1.3 (direct)

Rule 14.11 (direct)

QAC++

QAC++

QAC++

QAC++

Rule 2.3 Enclose all code in header files within include guards. Rule 14.11 (direct) QAC++

Rec. 2.4 Definitions for inline member functions should be placed

in a separate file.

Guideline 8.1.2 (direct)

Guideline 3.1.7 (avoids)

QAC++

QAC++

Rec 2.5 Definitions for all template functions of a class should be

placed in a separate file.

Guideline 8.1.3 (direct) QAC++

Rec 3.1 Each file should contain a single copyright comment. Maintenance

Rec 3.2 Each file should contain a comment with a short

description of the file content.

Maintenance

Rec 3.3 Every file should declare a local constant string that

identified the file.

Maintenance

Rec 3.4 Use // for comments. Rule 14.1 (direct) QAC++

Rec 3.5 All comments should be written in English Maintenance

Rule 4.1 Do not change a loop variable inside a for loop block. Rule 5.5 (direct)

Rule 5.6 (direct)

QAC++

QAC++

Rec 4.2 Update loop variables close to where the loop condition

is specified.

Maintenance

Rec 4.3 All flow control primitives (if, else, while, for, do,

switch, and case) should be followed by a block, even if

it is empty.

Rule 5.1 (direct) QAC++

Rec 4.4 Statements following a case label should be terminated

by a statement that exits the switch statement.

Rule 5.4 (direct) QAC++

Rec 4.5 All switch statements should have a default clause. Rule 5.11 (direct) QAC++

Rule 4.6 Use break and continue instead of goto. Rule 5.8 (direct) QAC++

Rec 4.7 Do not have overly complex functions. Rule 4.1 (direct)

Rule 4.2 (direct)

Rule 4.3 (direct)

QAC++

QAC++

QAC++

Rec 5.1 Declare and initialise variables close to where they are

used.

Rule 8.4.4 (direct)

Maintenance

No auto

Rec 5.2 If possible, initialise variables at the point of declaration. Rule 8.4.3 (direct) QAC++

Rec 5.3 Declare each variable in a separate declaration statement. Rule 8.4.2 (direct) QAC++

Rec 5.4 Literals should be used only in the definition of constants

and enumerations.

Rule 10.1 (direct) QAC++

Page 99: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1-2

Industrial Strength C++ Item Control Enforced

Rec 5.5 Initialise all data members. Rule 3.2.1 (direct)

Rule 8.4.3 (direct)

QAC++

QAC++

Rule 5.6 Let the order in the initialiser list be the same as the

order of declaration in the header file: first base classes,

then data members.

Rule 3.2.2 (direct) QAC++

Rec 5.7 Do not use or pass this in constructor initialiser lists. New Rule (2) QAC++

Rec 5.8 Avoid unnecessary copy of objects that are costly to

copy.

Rule 11.4 (avoids) QAC++

Rule 5.9 A function must never return, or in any other way give

access to, reference or pointers to local variables outside

the scope in which they are declared.

Rule 11.7 (direct) QAC++

Rec 5.10 If objects of a class should never be copied, then the

copy constructor and the copy assignment operator

should be declared private and not implemented.

Rule 3.1.3 (direct) QAC++

Rec 5.11 A class that manages resources should declare a copy

constructor, a copy assignment operator, and a

destructor.

Rule 3.1.3 (direct)

Rule 3.1.13 (direct)

QAC++

QAC++

Rule 5.12 Copy assignment operators should be protected from

doing destructive actions if an object is assigned to itself.

Rule 3.1.5 (direct) QAC++

Rec 6.1 Use explicit rather than implicit type conversions. Rule 3.1.11 (direct)

Rule 3.2.3

Guideline 7.2 (direct)

Rule 7.8 (direct)

Guideline 10.7 (direct)

QAC++

QAC++

QAC++

QAC++

QAC++

Rec 6.2 Use the new cast operators (dynamic_cast, const_cast,

reinterpret_cast, and static_cast) instead of the old-style

casts, unless portability is an issue.

Rule 7.1 (direct) QAC++

Rec 6.3 Do not cast away const. Rule 7.4 (direct) QAC++

Rule 6.4 Declare a data member mutable if it must be modified by

a const member function.

Rule 3.1.8 (avoids)

Rule 7.4 (avoids)

QAC++

QAC++

Rec 7.1 Make simple functions inline. Rule 11.8 (direct)

Rule 3.1.6 (direct)

QAC++

QAC++

Rule 7.2 Do not declare virtual member functions as inline. Rule 11.8

Rule 3.1.6

QAC++

QAC++

Rec 7.3 Pass arguments of built-in types by value unless the

function should modify them.

Rule 11.5 (direct) No auto

Rec 7.4 Use a parameter of pointer type only if the function

stores the address or passes it to a function that does.

Rule 11.4 (direct) QAC++

Rec 7.5 Pass arguments of class types by reference or pointer. Rule 11.4 (direct) QAC++

Rule 7.6 Pass arguments of class types by reference or pointer if

the class is meant as a public base class.

Rule 11.4 (direct)

Rule 11.5 (direct)

Software Engineering –

Object Oriented Design

QAC++

PC-Lint partial

Rule 7.7 The copy assignment operator should return a non-const

reference to the object assigned to.

Rule 3.1.5 (direct) QAC++

Rule 7.8 A pointer or reference parameter should be declared

const if the function does not change the object bound to

it.

Rule 11.4 (direct)

Rule 11.5 (direct)

QAC++

PC-Lint partial

Rule 7.9 The copy constructor and copy assignment operator

should always have a const reference as a parameter.

Rule 3.1.5 (direct) QAC++

Rule 7.10 Use only const char-pointers to access string literals. ISO C++ defines

Rule 7.11 A member function that does not change the state of a

program should be declared const.

Rule 3.1.8 (direct) QAC++

Rule 7.12 A member function that gives non-const access to the

representation of an object must not be declared as const.

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

QAC++

QAC++

Rule 7.13 Do not let const member functions change the state of

the program.

Rule 3.1.8 (direct) QAC++

Rule 7.14 All variants of an overloaded member function should be

used for the same purpose and have similar behaviour.

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

No auto

QAC++

Page 100: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1-3

Industrial Strength C++ Item Control Enforced

Rec 7.15 If you overload one out of a closely-related set of

operators, then you should overload the whole set and

preserve the same invariants that exist for built in types.

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

Maintenance

Software Engineering –

Object Oriented Design

No auto

QAC++ partial

PC-Lint partial

Rule 7.16 In a derived class, if you need to override one of a set of

base class’s overloaded virtual member functions, then

you should override the whole set, or use using-

declarations to bring all of the functions in the same base

class into the scope of the derived class.

Rule 3.3.5 (direct)

Rule 3.3.11 (direct)

QAC++

QAC++

Rule 7.17 Supply default arguments with the function’s declaration

in the header file, not with the function’s definition in the

implementation file.

Rule 3.3.12 (direct)

Rule 12.1 (avoids)

Maintenance

QAC++

No auto

Rec 7.18 One-argument constructors should be declared explicit. Rule 3.2.3 (direct)

Rule 7.8 (avoids)

QAC++

QAC++

Rec 7.19 Do not use conversion functions. Rule 3.1.10 (direct)

Rule 3.1.11 (direct)

QAC++

QAC++

Rule 8.1 Delete should only be used with new. Rule 12.3 (direct) QAC++

Rule 8.2 Delete[] should only be used with new[]. Rule 12.3 (direct) QAC++

Rule 8.3 Do not access a pointer or reference to a deleted object. Rule 12.8 (avoids) QAC++ partial

PC-Lint partial

Rec 8.4 Do not delete this. New Rule (4) QAC++

Rec 8.5 If you overloaded operator new for a class, you should

have overloaded operator delete.

Rule 12.6 (direct) QAC++

Rec 8.6 Customise the memory management for a class if

memory management is an unacceptably large part of the

allocation and deallocation of free store objects of that

class.

Efficiency

Rec 9.1 Objects with static storage duration should be declared

only within the scope of a class, function, or anonymous

namespace.

Rule 8.1.1 (direct)

Rule 8.1.2 (direct)

Rule 8.2.2 (direct)

Guideline 6.6 (supports)

QAC++

QAC++

QAC++

No auto

Rec 9.2 Document how static objects are initialised. Rule 8.2.2 (direct)

Guideline 8.3.2 (avoids)

Maintenance

QAC++

No auto

Rule 10.1 Declare data members private. Rule 3.4.1 (direct) QAC++

Rec 10.2 If a member function returns a pointer or reference, you

should document how it should be used and how long it

is valid.

Maintenance

Rec 10.3 Selection statements (if-else and switch) should be used

when the control flow depends on an object’s value;

dynamic binding should be used when the control flow

depends on the object’s type.

Software Engineering –

Object Oriented Design

Rule 10.4 A public base class must have either a public virtual

destructor or a protected destructor.

Rule 3.3.2 (direct)

Guideline 17.7 (direct)

QAC++

No auto

Rule 10.5 If you derive from more than one base class with the

same parent, that parent should be a virtual base class.

Rule 3.3.15 (direct) QAC++

Rec 10.6 Specify classes using preconditions, postconditions,

exceptions, and class invariants.

Software Engineering –

Object Oriented Design

Malpas

Rec 10.7 Use C++ to describe preconditions, postconditions,

exceptions and class invariants.

Software Engineering –

Object Oriented Design

Rec 10.8 It should be possible to use a pointer or reference to an

object of a derived class whenever a pointer or reference

to public base class object is used.

Rule 3.3.3 (direct)

ISO C++ defines

QAC++

Rec 10.9 Document the interface of template parameters. Maintenance

Rule 11.1 Do not let assertions change the state of the program. Rule 10.8 (direct) No auto

Rec 11.2 Remove all assertions from production code. Rule 10.8 (direct)

Efficiency

No auto

Page 101: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1-4

Industrial Strength C++ Item Control Enforced

Rec 12.1 Check for all errors reported from functions. Guideline 9.4 (direct)

Software Engineering –

Exception Design

No auto

Rec 12.2 Use exception handling instead of status values and error

codes.

Guideline 9.4 (direct)

Software Engineering –

Exception Design

No auto

Rec 12.3 Throw exceptions only when a function fails to do what

it is expected to do.

Guideline 9.4 (direct)

Software Engineering –

Exception Design

No auto

Rec 12.4 Do not throw exceptions as a way of reporting

uncommon values from a function.

Guideline 9.4 (direct)

Software Engineering –

Exceptions Design

No auto

Rule 12.5 Do not let destructors called during stack unwinding

throw exceptions.

Rule 9.1 (avoids) QAC++

Rec 12.6 Constructors of types thrown as exceptions should not

themselves throw exceptions.New Rule (11) QAC++

Rec 12.7 Use objects to manage resources. Software Engineering –

Object Oriented Design

and Exception Design

Rule 12.8 A resource managed by an object must be released by the

object’s destructor.

Rule 3.2.5 (direct) QAC++ partial

PC-Lint partial

Rec 12.9 Use stack objects instead of free store objects. New Guideline (15)

Rec 12.10 Before letting any exceptions propagate out of a member

function, make certain that the class invariant holds and,

if possible, leave the state of the object unchanged.

Guideline 9.5 (direct)

Guideline 9.6 (direct)

Rule 9.1 (direct)

Software Engineering –

Object Oriented Design

and Exception Design

No auto

No auto

QAC++

Rec 12.11 Throw only objects of class type. Rule 9.2 (direct) QAC++

Rec 12.12 Group related exception types by using inheritance. Rule 9.2 (direct)

Software Engineering –

Object Oriented Design

and Exception Design

QAC++

Rec 12.13 Catch only objects by reference. Rule 9.3 (direct) QAC++

Rule 12.14 Always catch exceptions the user is not supposed to

know about.

Software Engineering –

Exception Design

Rec 12.15 Do not catch exceptions you are not supposed to know

about.

Software Engineering –

Exception Design

Rec 12.16 Use exception specifications to declare which exceptions

might be thrown from a function.

Guideline 9.4 (direct)

Software Engineering –

Exception Design

QAC++ partial

Rec 13.1 Use new and delete instead of malloc, calloc, realloc, and

free.

Rule 12.2 (direct)

Rule 17.1 (direct)

QAC++

QAC++

Rule 13.2 Use the iostream library instead of C-style I/O. Rule 17.1 (direct)

Rule 17.2 (direct)

QAC++

No auto

Rule 13.3 Do not use setjmp() and longjmp(). Rule 17.1 (direct)

Rule 17.2 (direct)

QAC++

No auto

Rec 13.4 Use overloaded functions and chained function calls

instead of functions with an unspecified number of

arguments.

Rule 4.3 (direct) QAC++

Rule 13.5 Do not use macros instead of constants, enums,

functions, or type definitions.

Rule 14.17 (avoids)

Rule 14.14 (avoids)

Rule 14.15 (direct)

QAC++

QAC++

QAC++

Rec 13.6 Use an array class instead of built-in arrays. Rule 8.4.8 (direct)

Rule 8.4.9 (direct)

Rule 17.9 (direct)

QAC++

QAC++

No auto

Rec 13.7 Do not use unions. Rule 15.1 (direct) QAC++

Page 102: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1-5

Industrial Strength C++ Item Control Enforced

Rec 14.1 Avoid duplicated code and data. Rule 3.1.6 (avoids)

Rule 11.8 (avoids)

Software Engineering –

Object Oriented Design

QAC++

QAC++

Rule 14.2 When a public base class has a virtual destructor, each

derived class has a virtual destructor.

Rule 3.3.2 (direct)

Rule 3.1.13 (direct)

QAC++

QAC++

Rule 15.1 Do not depend on undefined, unspecified, or

implementation-defined parts of the language.

Refer to Appendixes 8 -

14

Rule 15.2 Do not depend on extensions to the language or standard

library.

Guideline 13.2 (direct)

Rule 13.4 (direct)

PC-Lint partial

QAC++

Rec 15.3 Make nonportable code easy to find and replace. Maintenance

Rule 15.4 Headers supplied by the implementation should go in <>

brackets; all other headers should go in “” quotes.

Rule 14.9 (direct) QAC++

Rec 15.5 Do not specify absolute directory names in include

directives.

Rule 14.10 (direct) QAC++

Rec 15.6 Include file names should always be treated as case-

sensitive.

Rule 14.12 (direct) QAC++

Rule 15.7 Do not make assumptions about the size and layout in

memory of an object.

Rule 13.6 (direct)

Software Engineering -

Design

QAC++

Rule 15.8 Do not cast a pointer to a shorter quantity to a pointer to

a longer quantity.

Rule 13.7 (direct) QAC++

Rec 15.9 If possible, use plain int to store, pass, or return integer

values.

Efficiency

Rule 15.10 Make sure all conversions from a value of one type to

another narrower type do not slice off significant data.

Rule 3.3.3 (direct)

Rule 7.1 (direct)

Guideline 7.2 (direct)

Rule 11.4 (direct)

Rule 17.5 (direct)

QAC++

QAC++

QAC++

QAC++

No auto

Rec 15.11 Use typedefs or classes to hide representation of

application-specified data types.

Guideline 8.4.6 (direct)

Rule 15.2 (avoids)

Software Engineering –

Object Oriented Design

No auto

QAC++

Rec 15.12 Always prefix global names (such as externally visible

classes, functions, variables, constants, typedefs, and

enums) if namespace is not supported by the compiler.

Fully compliant ISO

C++ compiler only

Rec 15.13 Use macros to prevent unsupported keywords. Fully compliant ISO

C++ compiler only

Rec 15.14 Do not reuse variables declared inside a for loop. ISO C++ defines

Rec. 15.15 Only one include directive should be needed when using

a template.

Guideline 8.1.3 (direct) QAC++

Rec 15.16 Do not rely on partial instantiations of templates Rule 16.3 (direct) No auto

Rec 15.17 Do not rely on the lifetime of temporaries. ISO C++ defines

Rec 15.18 Do not use pragmas. Rule 13.4 (direct) QAC++

Rule 15.19 Always return a value from main(). ISO C++ defines

Rec 15.20 Do not depend on the order of evaluation of arguments to

a function.

Rule 10.3 (direct) QAC++

A.1 Do not mix coding styles within a group of closely

related classes.

Maintenance

A.2 In names that consist of more than one word, the words

are written together and each word other than the first

begins with an uppercase letter.

Maintenance

A.3 The names of classes, typedefs, and enumerated types

should begin with uppercase letters.

Maintenance

A.4 The names of variables and functions should begin with

lowercase letters.

Maintenance

A.5 Let data members have an M suffix. Maintenance

A.6 The names of macros should be uppercase. Maintenance

Page 103: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

1-6

Industrial Strength C++ Item Control Enforced

A.7 The name of an include guard should be the name of the

header file, with all illegal characters replaced by

underscores and all letters converted to uppercase.

Rule 14.11 (direct)

Maintenance

QAC++

A.8 Do not use letters that can be mistaken for digits, and

vice versa.

Rule 8.4.1 (direct) QAC++

A.9 Header files should have the extension .hh. Maintenance

A.10 Inline definition files should have the extension .icc. Maintenance

Guideline 3.1.7 QAC++

A.11 The names of parameters to functions should be

specified in the function declaration if the type name is

insufficient to describe the parameter.

Rule 11.3 (direct)

Maintenance

QAC++

A.12 Always provide an access specifier for base classes and

data members.

Rule 3.1.1 (direct) QAC++

A.13 The public, protected and private sections of a class

should be declared in that order.

Rule 3.1.1 (direct) QAC++

A.14 The keyword struct should be used only for a C-style

struct.

Rule 15.2 (direct) QAC++

A.15 Define inline member functions outside the class

definition.

Rule 3.1.6 (direct)

Guideline 3.1.7 (direct)

QAC++

QAC++

A.16 Write unary operators together with their operands. Guideline 8.4.12 (direct) No auto

A.17 Write access operators together with their operands. Maintenance

A.18 Do not access static members with . or ->. Maintenance

Table 1-1: HICPP Coverage of Industrial Strength C++ Items

Page 104: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

2-1

Appendix 2 – HICPP Coverage of Effective C++ Items

The following table details the HICPP coverage of the items presented in Effective C++ [Mey98].

Effective C++ Item Control Enforced

Item 1 Prefer const and inline to #define. Rule 8.4.11 (direct)

Rule 14.17 (direct)

PC-Lint partial

QAC++

Item 2 Prefer <iostream> to <stdio.h>. Rule 17.1 (direct) QAC++

Item 3 Prefer new and delete to malloc and free. Rule 12.2 (direct) QAC++

Item 4 Prefer C++ style comments. Rule 14.1 (direct) QAC++

Item 5 Use the same form in corresponding uses of new and delete. Rule 12.3 (direct) QAC++

Item 6 Use delete on pointer members in destructors. Rule 3.2.5 (direct) PC-Lint partial

QAC++ partial

Item 7 Be prepared for out-of-memory conditions. New Guideline (16)

Software Engineering -

Design

No auto

Item 8 Adhere to convention when writing operator new and

operator delete.

Rule 12.6 (direct)

Rule 12.7 (direct)

Rule 3.5.2 (direct)

QAC++

QAC++

No auto

Item 9 Avoid hiding the “normal” form of new. Rule 3.3.11 (direct)

Rule 8.2.1 (avoids)

QAC++

QAC++

Item 10 Write operator delete if you write operator new. Rule 12.6 (direct) QAC++

Item 11 Declare a copy constructor and an assignment operator for

classes with dynamically allocated memory.

Rule 3.1.3 (direct)

Rule 3.1.13 (direct

QAC++

QAC++

Item 12 Prefer initialisation to assignment in constructors. Rule 3.1.2 (direct)

Rule 3.2.1 (direct)

Efficiency

QAC++

QAC++

Item 13 List members in an initialisation list in the order in which

they are declared.

Rule 3.2.2 (direct) QAC++

Item 14 Make sure base classes have virtual functions. Rule 3.3.2 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 15 Have operator= return a reference to *this. Rule 3.1.5 (direct)

Rule 3.5.2 (direct)

QAC++

No auto

Item 16 Assign all data members in operators. Rule 3.1.5 (direct) QAC++

Item 17 Check for assignment to self in operator=. Rule 3.1.5 (direct) QAC++

Item 18 Strive for class interfaces that are complete and minimal. Rule 3.1.11 (direct)

Rule 3.1.13 (direct)

Guideline 3.5.5 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

QAC++

Item 19 Differentiate among member functions, non-member

functions, and friend functions.

Rule 3.5.4 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 20 Avoid data members in the public interface. Rule 3.4.1 (direct) QAC++

Item 21 Use const whenever possible. Rule 3.1.8 (direct)

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

Rule 3.5.3 (direct)

Rule 8.4.11 (direct)

QAC++

QAC++

QAC++

QAC++

PC-Lint partial

Item 22 Prefer pass-by-reference to pass-by-value. Rule 3.5.3 (direct)

Rule 11.4 (direct)

QAC++

QAC++

Item 23 Don’t try to return a reference when you must return an

object.

Rule 3.5.3 (direct)

Rule 11.7 (direct)

QAC++

QAC++

Item 24 Choose carefully between function overloading and

parameter defaulting.

Rule 3.3.12 (direct)

Rule 12.1 (direct)

Software Engineering -

Design

QAC++

PC-Lint partial

Item 25 Avoid overloading on a pointer and a numeric type. Rule 11.9 (direct) QAC++

Page 105: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

2-2

Effective C++ Item Control Enforced

Item 26 Guard against potential ambiguity. Programmer Skill

Item 27 Explicitly disallow use of implicitly generated member

functions you don’t want.

Rule 3.1.10 (direct)

Rule 3.1.11 (direct)

Rule 3.1.13 (direct)

Rule 3.2.3 (direct)

QAC++

QAC++

QAC++

QAC++

Item 28 Partition the global namespace. Rule 8.2.2 (direct)

Guideline 8.2.3 (direct)

Guideline 8.2.4 (direct)

Software Engineering -

Design

QAC++

QAC++

QAC++

Item 29 Avoid returning “handles” to internal data. Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

Rule 11.7 (direct)

Rule 12.5 (direct)

QAC++

QAC++

QAC++

No auto

Item 30 Avoid member functions that return non-const pointers or

references to members less accessible than themselves.

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

QAC++

QAC++

Item 31 Never return a reference to a local object or to a

dereferenced pointer initialised by new within the function.

Rule 12.5 (direct)

Rule 11.7 (direct)

No auto

QAC++

Item 32 Postpone variable definitions as long as possible. Maintenance

Efficiency

Item 33 Use inlining judiciously. Rule 3.1.6 (direct)

Guideline 3.1.7 (direct)

Rule 11.8 (direct)

QAC++

QAC++

QAC++

Item 34 Minimise compilation dependencies between files. Guideline 8.1.1 (direct)

Guideline 8.1.2 (direct)

Guideline 8.1.3 (direct)

Rule 14.5 (direct)

Rule 14.13 (direct)

QAC++

QAC++

QAC++

QAC++

QAC++

Item 35 Make sure public inheritance models “isa”. Rule 3.3.1 (direct) QAC++

Item 36 Differentiate between inheritance of interface and

inheritance of implementation.

Rule 3.3.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 37 Never redefine an inherited nonvirtual function. Rule 3.3.11 (direct) QAC++

Item 38 Never redefine an inherited default parameter value. Rule 3.3.12 (direct) QAC++

Item 39 Avoid casts down the inherited hierarchy. Rule 3.3.3 (direct) QAC++

Item 40 Model “has-a” or “is-implemented-in-terms-of” through

layering.

Rule 3.3.1 (direct)

Guideline 16.4 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Item 41 Differentiate between inheritance and templates. Guideline 16.4 (direct)

Software Engineering –

Object Oriented Design

No auto

Item 42 Use private inheritance judiciously. Rule 3.3.1 (avoids) QAC++

Item 43 Use multiple inheritance judiciously. Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Item 44 Say what you mean, understand what you’re saying. Programmer Skill

Item 45 Know what functions C++ silently writes and calls. Programmer Skill

Item 46 Prefer compile-time and link-time errors to run-time errors. Software Engineering -

Design

Use of a Subset

Item 47 Ensure that non-local static objects are initialised before

they are used.

Rule 8.2.2 (avoids)

Guideline 6.6 (direct)

QAC++

No auto

Item 48 Pay attention to compiler warnings. Programmer Attitude

Programmer Skill

Item 49 Familiarise yourself with the standard library. Programmer Skill

Item 50 Improve your understanding of C++ Programmer Skill

Table 2-1: HICPP Coverage of Effective C++ Items

Page 106: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

3-1

Appendix 3 – HICPP Coverage of More Effective C++ Items

The following table details the HICPP coverage of the items presented in More Effective C++

[Mey96].

More Effective C++ Item Control Enforced

Item 1 Distinguish between pointers and references. Software Engineering

Item 2 Prefer C++ style casts. Rule 7.1 QAC++

Item 3 Never treat arrays polymorphically. Rule 8.4.9 (avoids)

Rule 17.9 (avoids)

Rule 3.3.3 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

QAC++

Item 4 Avoid gratuitous default constructors. Software Engineering –

Object Oriented Design

Programmer Skill

Efficiency

Item 5 Be wary of user-defined conversion functions. Rule 3.1.10 (direct)

Rule 3.1.11 (direct)

QAC++

QAC++

Item 6 Distinguish between prefix and postfix forms of increment

and decrement operators.

Software Engineering -

Design

Programmer Skill

Item 7 Never overload &&, ||, or ,. Rule 3.5.1 (direct) QAC++

Item 8 Understand the different meanings of new and delete. Programmer Skill

Item 9 Use destructors to prevent resource leaks. Rule 3.2.5 (direct)

Guideline 9.5 (direct)

Rule 12.3 (direct)

Guideline 17.21 (direct)

QAC++ partial

PC-Lint partial

No auto

QAC++

No auto

Item 10 Prevent resource leaks in constructors. Guideline 9.5 (direct)

Guideline 17.21 (direct)

No auto

No auto

Item 11 Prevent exceptions from leaving destructors. Rule 9.1 (direct) QAC++

Item 12 Understand how throwing an exception differs from passing

a parameter or calling a virtual function.

Rule 8.4.3 (direct)

Programmer Skill

QAC++

Item 13 Catch exceptions by reference. Rule 9.3 (direct) QAC++

Item 14 Use exception specifications judiciously. Programmer Skill

Software Engineering –

Exception Design

Guideline 9.6 (direct) No auto

Item 15 Understand the costs of exception handling. Software Engineering –

Exception Design

Programmer Skill

Efficiency

Item 16 Remember the 80-20 rule. Efficiency

Item 17 Consider using lazy evaluation. Efficiency

Item 18 Amortize the cost of expected computations. Efficiency

Item 19 Understand the origins of temporary objects. Efficiency

Programmer Skill PC-Lint partial

Item 20 Facilitate the return value optimisation. Efficiency

Item 21 Overload to avoid implicit type conversions. Guideline 10.7 (direct)

Efficiency

QAC++

Item 22 Consider using op= instead of stand alone op. Efficiency

Item 23 Consider alternatives to libraries Efficiency

Rule 17.1 (direct) QAC++

Item 24 Understand the costs of virtual functions, multiple

inheritance, virtual base classes, and RTTI.

Efficiency

Programmer Skill

Item 25 Virtualising constructors and non-member functions. Software Engineering –

Object Oriented Design

Page 107: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

3-2

More Effective C++ Item Control Enforced

Item 26 Limiting the number of objects in a class. Software Engineering –

Object Oriented Design

Item 27 Requiring or prohibiting heap-based objects. Software Engineering -

Design

Item 28 Smart pointers. Software Engineering -

Design

Rule 16.1 (avoids) QAC++

Item 29 Reference counting. Software Engineering –

Object Oriented Design

Item 30 Proxy classes. Software Engineering –

Object Oriented Design

Item 31 Making functions virtual with respect to more than one

object.

Software Engineering –

Object Oriented Design

Item 32 Program in the future tense. Rules and Guidelines

HICPP

Software Engineering -

Design

Item 33 Make non-leaf classes abstract. Rule 3.3.14 (direct)

Rule 3.4.5 (direct)

QAC++

QAC++

Item 34 Understand how to combine C++ and C in the same

program.

Programmer Skill

Software Engineering –

Design

Item 35 Familiarise yourself with the language standard. Programmer Skill

Table 3-1: HICPP Coverage of More Effective C++ Items

Page 108: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

4-1

Appendix 4 – HICPP Coverage of Effective STL Items

The following table details the HICPP coverage of the items presented in Effective STL [Mey01].

Effective STL Item Control Enforced

Item 1 Choose your containers with care. Programmer Skill

Software Engineering –

Design and Efficiency

Item 2 Beware the illusion of container-independent code. Programmer Skill

Software Engineering –

Design

Item 3 Make copying cheap and correct for objects in containers. Guideline 17.3 (direct)

Guideline 17.4 (direct)

Rule 17.5 (direct)

No auto

No auto

No auto

Item 4 Call empty instead of checking size() against zero. Rule 17.6 (direct) No auto

Item 5 Prefer range member functions to their single-element

counterparts.

Software Engineering –

Design and Efficiency

Item 6 Be alert for C++’s most vexing parse. Programmer Skill

Item 7 When using containers of newed pointers, remember to

delete the pointers before the container is destroyed.

Rule 17.5 (direct)

Rule 3.2.5 (direct)

No auto

No auto

Item 8 Never create containers of auto_ptrs. Rule 17.8 (direct) No auto

Item 9 Choose carefully among erasing options. New Guideline (21)

Software Engineering –

Design

Programmer Skill

No auto

Item 10 Be aware of allocator conventions and restrictions. New Guideline (22)

Software Engineering –

Design

Programmer Skill

No auto

Item 11 Understand the legitimate uses of custom allocators. New Guideline (22)

Software Engineering –

Design

Programmer Skill

No auto

Item 12 Have realistic expectations about the thread safety of STL

containers.

Software Engineering –

Design

Item 13 Prefer vector and string to dynamically allocated arrays. Rule 17.9 (direct) No auto

Item 14 Use reserve to avoid unnecessary re-allocations. Rule 17.10 (avoid) No auto

Item 15 Be aware of variations in string implementations. Rule 13.6 (direct)

Programmer Skill

Software Engineering –

Design

QAC++ partial

Item 16 Know how to pass vector and string data to legacy APIs. Rule 17.11 (direct)

Rule 17.12 (direct)

No auto

No auto

Item 17 Use “the swap trick” to trim excess capacity. Software Engineering –

Design

Efficiency

Item 18 Avoid using vector<bool>. Rule 17.13 (direct) No auto

Item 19 Understand the difference between equality and equivalence. Programmer Skill

Software Engineering –

Design

No auto

Item 20 Specify comparison types for associative containers of

pointers.New Guideline (23)

Software Engineering -

Design

Programmer Skill

No auto

Item 21 Always have comparison functions return false for equal

values.

Rule 17.14 (direct) No auto

Item 22 Avoid in-place key modification in set and multiset. Rule 17.15 (direct) No auto

Item 23 Consider replacing associative containers with sorted

vectors.

Software Engineering –

Design and Efficiency

Page 109: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

4-2

Effective STL Item Control Enforced

Item 24 Choose carefully between map::operator[] and map::insert

when efficiency is important..

Programmer Skill

Software Engineering –

Design

Item 25 Familiarise yourself with the non-standard hashed

containers.

Not part of ISO C++

Item 26 Prefer iterator to const_iterator, reverse_iterator, and

const_reverse_iterator.

Guideline 17.16

(direct)

No auto

Item 27 Use distance and advance to convert a container’s

const_iterators to iterators.

Guideline 17.16

(direct)

No auto

Item 28 Understand how to use a reverse_iterator’s base iterator. Rule 17.17 (direct) No auto

Item 29 Consider istreambuf_iterators for character-by-character

input.

Software Engineering –

Design

Efficiency

Item 30 Make sure destination ranges are big enough. Guideline 17.10

(avoid)

Programmer Skill

New Rule (24)

No auto

No auto

Item 31 Know your sorting options. Programmer Skill

Item 32 Follow remove-like algorithms by erase if you really want to

remove something.

Programmer Skill

Item 33 Be wary of remove-like algorithms on containers of

pointers.New Rule (25) No auto

Item 34 Note which algorithms expected sort ranges. Programmer Skill

Software Engineering –

Design

Item 35 Implement simple case-insensitive string comparisons via

mismatch or lexicographical_compare.

Software Engineering –

Design

Item 36 Understand the proper implementation of copy_if. Not in ISO C++

Item 37 Use accumulate or for_each to summarise ranges. Software Engineering –

Design

Item 38 Design functor classes for pass-by-value. Software Engineering –

Design

Item 39 Make predicates pure functions. Rule 17.17 (direct) No auto

Item 40 Make functor classes adaptable. Software Engineering –

Design

Maintenance

Item 41 Understand the reasons for ptr_fun, mem_fun, and

mem_fun_ref.

Programmer Skill

Item 42 Make sure less<T> means operator<. Software Engineering –

Design

Maintenance

Item 43 Prefer algorithm calls to hand-written loops. Guideline 17.18

(direct)

No auto

Item 44 Prefer member functions to algorithms with the same names. Rule 17.19 (direct) No auto

Item 45 Distinguish amount count, find, binary_search, lower_upper,

upper_bound, and equal_range.

Software Engineering –

Design

Item 46 Consider function objects instead of functions as algorithm

parameters.

Programmer Skill

Efficiency

Software Engineering –

Design

Item 47 Avoid producing write only code. Maintenance

Software Engineering –

Design

Item 48 Always #include the proper headers. Rule 17.20 (direct) No auto

Item 49 Learn to decipher STL-related compiler diagnostics. Programmer Skill

Item 50 Familiarise yourself with the STL-related web-sites. Programmer Skill

Table 4-1: HICPP Coverage of Effective STL Items

Page 110: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

5-1

Appendix 5 – HICPP Coverage of C++ Gotchas

The following table details the HICPP coverage of the items presented in C++ Gotchas [Dew03].

C++ Gotchas Item Control Enforced

Item 1 Excessive Commenting Rule 14.1 (direct)

Maintenance

QAC++ partial

PC-Lint partial

Item 2 Magic Numbers Rule 14.17 (direct)

Maintenance

QAC++

Item 3 Global Variables Rule 8.2.2 (direct)

Guideline 6.6 (direct)

QAC++

No auto

Item 4 Failure to Distinguish Overloading from Default

Initialisation

Rule 12.1 (direct)

Programmer Skill

QAC++ partial

PC-Lint partial

Item 5 Misunderstanding References Software Engineering –

Design

Programmer Skill

Item 6 Misunderstanding Const Programmer Skill

Item 7 Ignorance of Base Language Subtleties Rule 5.1 (direct)

Rule 5.4 (direct)

Rule 10.20 (direct)

Programmer Skill

QAC++

QAC++

QAC++

Item 8 Failure to Distinguish Access and Visibility Guideline 8.1.1 (direct)

Guideline 8.1.2 (direct)

Guideline 8.1.3 (direct)

Software Engineering –

Object Oriented Design

Programmer Skill

Maintenance

QAC++

QAC++

QAC++

Item 9 Use Bad Language Rule 14.16 (direct)

Programmer Skill

QAC++

Item 10 Ignorance of Idiom Rule 3.1.3 (direct)

Rule 3.1.13 (direct)

Guideline 17.21 (avoids)

Programmer Skill

QAC++

QAC++

No auto

Item 11 Unnecessary Cleverness Rule 8.4.1 (direct)

Rule 8.4.2 (direct)

Rule 8.4.4 (direct)

Programmer Attitude

Maintenance

QAC++

QAC++

No auto

Item 12 Adolescent Behaviour Programmer Attitude

Item 13 Array/Initialiser Confusion Rule 8.4.9 (direct)

Rule 10.2 (direct)

Rule 12.3 (direct)

Rule 17.9 (direct)

Programmer Skill

QAC++

QAC++

QAC++

No auto

Item 14 Evaluation Order Indecision Rule 3.5.1 (direct)

Rule 10.3 (direct)

Rule 17.17 (avoids)

QAC++

QAC++

No auto

Item 15 Precedence Problems Rule 10.4 (avoids)

Rule 3.5.1 (direct)

QAC++

QAC++

Item 16 For Statement Debacle Rule 5.5 (direct)

Rule 5.6 (direct)

Guideline 5.7 (direct)

Rule 5.12 (direct)

Rule 8.2.1 (direct)

Rule 8.4.4 (avoids)

QAC++

QAC++

QAC++

QAC++

QAC++

No auto

Item 17 Maximal Munch Problems Rule 10.4 (direct)

Programmer Skill

QAC++

Page 111: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

5-2

C++ Gotchas Item Control Enforced

Item 18 Creative Declaration-Specifier Ordering Rule 8.4.11 (direct)

Rule 8.4.12 (direct)

Programmer Skill

Maintenance

PC-Lint partial

QAC++ partial

No auto

Item 19 Function/Object Ambiguity Programmer Skill

Item 20 Migrating Type-Qualifiers Rule 8.4.7 (direct)

Rule 8.4.11 (direct)

Programmer Skill

QAC++

No auto

Item 21 Self Initialisation Rule 8.2.1 (direct)

Rule 8.3.4 (direct)

New Rule 8

QAC++

QAC++

QAC++ partial

Item 22 Static and Extern Types Rule 8.3.1 (direct)

Rule 11.2 (avoids)

QAC++

No auto

Item 23 Operator Function Lookup Anomaly Programmer Skill

Item 24 Operator -> Subtleties Programmer Skill

Item 25 #define Literals Rule 14.17 (direct) QAC++

Item 26 #define Psuedofunctions Guideline 14.7 (direct)

Rule 14.14 (direct)

Rule 14.15 (direct)

QAC++

QAC++

QAC++

Item 27 Overuse of #if Software Engineering –

Design

Programmer Skill

Item 28 Side Effects in Assertions. Rule 10.8 (direct)

Rule 14.14 (avoids)

Rule 14.15 (avoids)

No auto

QAC++

QAC++

Item 29 Converting Through void * Rule 7.1 (direct)

Guideline 7.2 (avoids)

Rule 7.5 (direct)

Rule 7.7 (direct)

QAC++

QAC++

QAC++

QAC++

Item 30 Slicing Rule 3.3.4 (direct)

Rule 17.5 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Item 31 Misunderstanding Pointer-to-Const Conversion Guideline 7.2 (avoids)

Rule 7.4 (direct)

Rule 7.5 (direct)

Programmer Skill

QAC++

QAC++

QAC++

Item 32 Misunderstanding Pointer-to-Pointer-to-Const Conversion Guideline 7.2 (avoids)

Rule 7.4 (direct)

Rule 7.5 (direct)

Programmer Skill

QAC++

QAC++

QAC++

Item 33 Misunderstanding Pointer-to-Pointer-to-Base Conversion. Guideline 7.2 (avoids)

Rule 7.4 (direct)

Rule 7.5 (direct)

Programmer Skill

QAC++

QAC++

QAC++

Item 34 Pointer-to-Multidimensional-Array Problems Rule 8.4.9 (avoids)

Rule 17.9 (direct)

Programmer Skill

QAC++

No auto

Item 35 Unchecked Downcasting Rule 3.3.3 (direct) QAC++

Item 36 Misusing Conversion Operators Guideline 7.2 (avoids)

Rule 3.1.10 (avoids)

Rule 3.1.11 (avoids)

Rule 3.2.3 (direct)

Rule 7.8 (avoids)

Rule 8.3.5 (direct)

Guideline 10.7 (avoids)

QAC++

QAC++

QAC++

QAC++

QAC++

No auto

QAC++

Item 37 Unintended Constructor Conversion Guideline 7.2 (avoids)

Rule 3.2.3 (direct)

QAC++

QAC++

Page 112: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

5-3

C++ Gotchas Item Control Enforced

Item 38 Casting under Multiple Inheritance Rule 3.4.6 (avoids)

Rule 7.1 (avoids)

Guideline 7.2 (avoids)

No auto

QAC++

QAC++

Item 39 Casting Incomplete Types Rule 3.1.13 (avoids)

Rule 7.1 (direct)

Guideline 7.2 (direct)

QAC++

QAC++

QAC++

Item 40 Old-Style Casts Rule 7.1 (direct)

Guideline 7.2 (direct)

QAC++

QAC++

Item 41 Static Casts Guideline 7.2 (direct) QAC++

Item 42 Temporary Initialisation of Formal Arguments. Rule 7.8 (direct)

Rule 11.4 (direct)

Rule 11.7 (direct)

Programmer Skill

QAC++

QAC++

QAC++

Item 43 Temporary Lifetime Rule 11.7 (direct) QAC++

Item 44 References and Temporaries Rule 11.7 (direct)

Programmer Skill

QAC++

Item 45 Ambiguity Failure of dynamic_cast Guideline 7.2 (direct) QAC++

Item 46 Misunderstanding Contravariance Guideline 8.4.10 (avoid)

Programmer Skill

QAC++

Item 47 Assignment/Initialisation Confusion. Rule 3.1.2 (direct) QAC++

Item 48 Improperly Scoped Variables. Rule 8.4.2 (direct)

Rule 8.4.3 (avoids)

Rule 8.4.4 (avoids)

QAC++

QAC++

QAC++

Item 49 Failure to Appreciate C++’s Fixation on Copy Operations. Rule 3.1.3 (direct)

Rule 3.1.5 (direct)

Rule 3.1.13 (direct)

Guideline 3.2.4 (direct)

QAC++

QAC++

QAC++

QAC++

Item 50 Bitwise Copy of Class Objects Rule 3.1.3 (direct)

Rule 3.1.5 (direct)

QAC++

QAC++

Item 51 Confusing Initialisation and Assignment in Constructors Rule 3.2.1 (direct)

Rule 3.2.2 (direct)

Programmer Skill

QAC++

QAC++

Item 52 Inconsistent Ordering of the Member Initialisation List Rule 3.2.1

Rule 3.2.2

Item 53 Virtual Base Default Initialisation Rule 3.3.15 (direct)

Rule 3.4.5 (direct)

Rule 3.4.6 (direct)

Rule 7.1 (direct)

Guideline 7.2 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

No auto

QAC++

QAC++ partial

Item 54 Copy Constructor Base Initialisation Rule 3.1.13 (direct) QAC++

Item 55 Runtime Static Initialisation Order Guideline 8.1.1 (direct)

Guideline 8.1.2 (direct)

Rule 8.2.2 (direct)

Guideline 6.6 (direct)

QAC++

QAC++

QAC++

No auto

Item 56 Direct versus Copy Initialisation Rule 3.1.2 (direct)

Programmer Skill

QAC++

Item 57 Direct Argument Initialisation Rule 3.1.2 (direct)

ISO C++ defines

QAC++

Item 58 Ignorance of the Return Value Optimisations Efficiency

Item 59 Initialising a Static Member in a Constructor Guideline 8.1.1 (direct)

Guideline 8.1.2 (direct)

Rule 8.2.2 (avoids)

Rule 8.3.1 (avoids)

Guideline 6.6 (avoids)

Software Engineer –

Object Oriented Design

QAC++

QAC++

QAC++

QAC++

QAC++

Item 60 Failure to Distinguish Scalar and Array Allocation Rule 12.3 (direct) QAC++

Page 113: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

5-4

C++ Gotchas Item Control Enforced

Item 61 Checking for Allocation Failure Guideline 9.4 (direct)

New Guideline (16)

Software Engineering –

Design

Programmer Skill

No auto

No auto

Item 62 Replacing Global New and Delete Rule 12.6 (direct)

Rule 12.7 (direct)

Software Engineering –

Object Oriented Design

Efficiency

QAC++

QAC++

Item 63 Confusing Scope and Activation of Member new and delete. Programmer Skill

Item 64 Throwing String Literals Rule 9.2 (direct)

Rule 9.3 (direct)

QAC++

QAC++

Item 65 Improper Exception Mechanics Rule 9.2 (direct)

Rule 9.3 (direct)

Software Engineering –

Exception Design

Programmer Skill

QAC++

QAC++

Item 66 Abusing Local Addresses Rule 11.7 (direct) QAC++

Item 67 Failure to Employ Resource Acquisition Is Initialisation Rule 8.4.3 (direct) QAC++

Item 68 Improper Use of auto_ptr Rule 17.8 (direct)

Guideline 17.21 (direct)

No auto

No auto

Item 69 Type Codes Software Engineering –

Object Oriented Design

Maintenance

QAC++

Item 70 Nonvirtual Base Class Destructor Rule 3.3.2 (avoids) QAC++

Item 71 Hiding Nonvirtual Functions Rule 3.3.11 (direct) QAC++

Item 72 Making Template Methods Too Flexible Guideline 16.4

Software Engineering –

Object Oriented Design

No auto

Item 73 Overloading Virtual Functions Rule 3.3.5 (direct) QAC++

Item 74 Virtual Functions with Default Argument Initialisers Rule 3.3.12 (direct)

Rule 12.1 (avoids)

QAC++

QAC++ partial

PC-Lint partial

Item 75 Calling Virtual Functions in Constructors and Destructors Rule 3.3.13 (direct)

Software Engineering

QAC++

Item 76 Virtual Assignment Software Engineering –

Object Oriented Design

Programmer Skill

Item 77 Failure to Distinguish among Overloading, Overriding, and

Hiding

Programmer Skill

Software Engineering –

Object Oriented Design

Item 78 Failure to Grok Virtual Functions and Overriding Programmer Skill

Software Engineering –

Object Oriented Design

Item 79 Dominance Issues Software Engineering –

Object Oriented Design

Item 80 Get/Set Interfaces Rule 3.1.6 (direct)

Rule 3.4.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

Item 81 Const and Reference Data Members Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

Rule 3.1.8 (direct)

Rule 7.4 (avoids)

QAC++

QAC++

QAC++

QAC++

Item 82 Not Understanding the Meaning of Const Member Functions Rule 3.4.2 (direct)

Programmer Skill

QAC++

Page 114: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

5-5

C++ Gotchas Item Control Enforced

Item 83 Failure to Distinguish Aggregation and Acquaintance Programmer Skill

Software Engineering –

Object Oriented Design

Item 84 Improper Operator Overloading Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

Item 85 Precedence and Overloading Rule 3.5.1 (direct)

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

Rule 3.5.4 (direct)

Rule 3.5.5 (direct)

QAC++

QAC++

QAC++

QAC++

QAC++

Item 86 Friend versus Member Operators Rule 3.5.4 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 87 Problems with Increment and Decrement Programmer Skill

Item 88 Misunderstanding Templated Copy Operations Programmer Skill

Software Engineering –

Object Oriented Design

Item 89 Arrays of Class Objects Rule 8.4.9 (avoids) QAC++

Item 90 Improper Container Substitutability Software Engineering –

Object Oriented Design

Item 91 Failure to Understand Protected Access Rule 3.4.4 (direct)

Programmer Skill

QAC++

Item 92 Public Inheritance for Code Reuse Rule 3.3.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 93 Concrete Public Base Classes Rule 3.4.5 (avoids) QAC++

Item 94 Failure to Employ Degenerate Hierarchies Software Engineering –

Object Oriented Design

Item 95 Overuse of Inheritance Rule 3.3.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 96 Type-Based Control Structures Software Engineering –

Object Oriented Design

Item 97 Cosmic Hierarchies Software Engineering –

Object Oriented Design

Item 98 Asking Personal Questions of an Object Software Engineering –

Object Oriented Design

Programmer Skill

Item 99 Capability Queries Software Engineering –

Object Oriented Design

Table 5-1: HICPP Coverage of C++ Gotchas

Page 115: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

6-1

Appendix 6 – HICPP Coverage of Exceptional C++ Items

The following table details the HICPP coverage of the items presented in Exceptional C++ [Sut00].

Exceptional C++ Item Control Enforced

Item 1 Never de-reference an invalid iterator. New Rule (26) No auto

Item 5 Never make exception safety an afterthought. Exception

safety affects a class’s design. It is never “just an

implementation detail”.

Software Engineering –

Exception Design

Item 6 Prefer passing objects by const& instead of passing by

value.

Rule 11.4 (direct)

Rule 11.5 (direct)

QAC++

PC-Lint partial

Prefer precomputing values that won’t change, instead of

recreating objects unnecessarily.

Efficiency

For consistency, always implement post increment in terms

of preincrement, otherwise your users will get surprising

(and often unpleasant) results.

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

No auto

QAC++

Prefer preincrement. Only use postincrement if you’re going

to use the original value.

Programmer Skill

Watch out for hidden temporaries created by implicit

conversions. One good way to avoid this is to make

constructors explicit when possible and avoid writing

conversion operators.

Rule 3.1.10 (avoids)

Rule 3.1.11 (avoids)

Rule 3.2.3 (avoids)

Programmer Skill

QAC++

QAC++

QAC++

Be aware of object lifetimes. Never, ever, ever return

pointers or references to local automatic objects. They are

completely unuseful because the calling code can’t follow

them, and (what’s worse) the calling code my try.

Rule 11.7 (direct) QAC++

Item 7 Re-use code – especially standard library code – instead of

handcrafting your own. It’s faster, easier and safer.

Rule 17.2 (direct) QAC++

Item 8 If a function isn’t going to handle (or translate or

deliberately absorb) an exception, it should allow the

exception to propagate up to a caller that can handle it.

New Rule (12)

Software Engineering –

Object Oriented Design

QAC++

PC-Lint

Always structure your code so that resources are correctly

freed and data is in a consistent state even in the presence of

an exception.

Guideline 9.5 (direct)

Guideline 9.6 (direct)

No auto

No auto

Observe the canonical exception safety rules: Never allow

an exception to escape from a destructor or from an

overloaded operator delete() or operator delete[](); write

every destructor and deallocation function as though it had

an exception specification of “throw()”.

Rule 9.1 (direct) QAC++

Item 9 Observe the canonical exception safety rules: In each

function, take the code that might emit an exception and do

all the work safety off to the side. Only then, when you

know that the real work has succeeded, should you modify

the program state (and clean up) using only non-throwing

operations.

Guideline 9.5 (direct)

Guideline 9.6 (direct)

Software Engineering –

Object Oriented Design

No auto

No auto

Item 10 Prefer cohesion. Always endeavour to give each piece of

code – each module, each class, each function – a single,

well-defined responsibility.

Guideline 3.1.9 (direct)

Software Engineering –

Object Oriented Design

No auto

“Exception-unsafe” and “poor design” go hand in hand. If a

piece of code isn’t exception safe, that’s generally ok and

can simply be fixed. But if a piece of code cannot be made

exception safe because of its underlying design, that almost

always is a signal of its poor design.

Software Engineering –

Object Oriented Design

Item 11 Understand the basic, strong, and nothrow exception safety

guarantees.

Programmer Skill

Item 13 Observe the canonical exception-safety rules: Always use

the “resource acquisition is initialisation” idiom to isolate

resource ownership and management.

Rule 8.4.3 (direct)

Software Engineering –

Object Oriented Design

QAC++

Page 116: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

6-2

Exceptional C++ Item Control Enforced

Item 15 Design with reuse in mind. Software Engineering –

Object Oriented Design

Item 18 Always be exception-aware. Know what code might emit

exceptions.

Programmer Skill

Item 20 Prefer writing “a op= b;” instead of “a = a op b;” (where op

stands for any operator). It’s clearer, and it’s often more

efficient.

Maintenance

Efficiency

If you supply a standalone version of an operator (for

example, operator+), always supply an assignment version

of the same operator (for example, operator+=) and prefer

implementing the forms in terms of the latter. Also, always

preserve the natural relationship between op and op= (where

op stands for any operator).

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

Software Engineering –

Object Oriented Design

No auto

QAC++

The standard requires that operators = () [] and -> must be

members, and class specific operators new, new[], delete,

and delete[] must be static members. For all other functions:

if the function is operator>> or operator<< for stream I/O, or

if it needs type conversions on its leftmost argument, or if it

can be implemented using the class’s public interface alone,

make it a nonmember (and friend if needed in the first two

cases) – if it needs to behave virtually, add a virtual member

function to provide the virtual behaviour and implement it in

terms of that – else make it a member.

Rule 12.7 (direct)

Guideline 3.4.7 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Always return stream references from operator<< and

operator>>.New Rule (1)

Rule 3.3.10

No auto

QAC++ partial

PC-Lint partial

Item 21 Make base class destructors virtual (unless you are certain

that no one will ever attempt to delete a derived object

through a pointer to base).

Rule 3.3.2 (direct) QAC++

When providing a function with the same name as an

inherited function, be sure to bring the inherited functions

into scope with a using-declaration if you don’t want to hide

them.

Rule 8.2.1 (avoids) QAC++

Never change the default parameters of overridden inherited

functions.

Rule 3.3.12 (direct) QAC++

Item 22 Never use public inheritance except to model true Liskov IS-

A and WORKS-LIKE-A. All overridden member functions

must require no more and promise no less.

Rule 3.3.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

Never inherit publicly to reuse code (in the base class);

inherit publicly in order to be reused (by code that uses base

objects polymorphically).

Rule 3.3.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

When modelling “is implemented in terms of”, always

prefer membership/containment, not inheritance. Use private

inheritance only when inheritance is absolutely necessary –

that is, when you need access to protected members or you

need to override a virtual function. Never use public

inheritance for code reuse.

Rule 3.3.1 (avoids)

Software Engineering –

Object Oriented Design

QAC++

Item 23 Know about and use design patterns. Programmer Skill

For widely used classes, prefer to use the compiler-firewall

idiom (Pimpl Idiom) to hide implementation details. Use an

opaque pointer (a pointer to a declared but undefined class)

declared as “struct XxxxImpl; XxxxImple * pimpl_;” to

store private members (including both state variables and

member functions).

Software Engineering –

Object Oriented Design

Item 24 Prefer containment (a.k.a. “composition”, “layering”, “HAS-

A”, “delegation”) to inheritance. When modelling IS-

IMPLEMENTED-IN-TERMS-OF, always prefer expressing

it using containment, not inheritance.

Rule 3.3.1 (direct)

Rule 3.4.5 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

No auto

Page 117: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

6-3

Exceptional C++ Item Control Enforced

Item 26 Never #include unnecessary header files. Rule 14.11 (direct)

Rule 14.13 (direct)

QAC++

PC-Lint partial

Prefer to #include <iosfwd> when a forward declaration of a

stream will suffice.

Rule 14.11 (direct)

Rule 14.13 (direct)

Maintenance

QAC++

PC-Lint partial

Never #include a header when a forward declaration will

suffice.

Rule 14.11 (direct)

Rule 14.13 (direct)

Maintenance

QAC++

PC-Lint partial

Item 28 Never inherit when composition is sufficient. Rule 3.3.1 (direct)

Software Engineering –

Object Oriented Design

QAC++

Item 30 Avoid inlining or detailed tuning until performance profiles

prove then need.

Rule 3.1.6 (direct)

Rule 3.1.7 (direct)

Rule 11.8 (direct)

QAC++

QAC++

QAC++

Item 34 Use namespaces wisely. If you write a class in some

namespace N, be sure to put all helper functions and

operators into N, too. If you don’t, you may discover

surprising effects in your code.

Guideline 8.1.1 (direct)

Guideline 8.1.2 (direct)

Guideline 8.1.3 (direct)

Guideline 8.2.3 (direct)

Guideline 8.2.4 (direct)

Rule 11.2

Programmer Skill

QAC++

QAC++

QAC++

QAC++

QAC++

No auto

Item 35 Understand the five major distinct memory stores, why

they’re different, and how they behave: stack (automatic

variables); free store (new/delete); heap (malloc/free); global

space (statics, global variables, file scope variables, and so

forth); const data (string literals, and so forth).

Programmer Knowledge

Prefer using the free store (new/delete). Avoid using the

heap (malloc/free).

Rule 12.2 (direct) QAC++

Item 36 Always provide both class-specific new (or new[]) and

class-specific delete (or delete[]) if you provide either.

Rule 12.6 (direct) QAC++

Always explicitly declare operator new() and operator

delete() as static functions. They are never nonstatic member

functions.

Rule 12.7 (direct) QAC++

Never treat arrays polymorphically. Rule 8.4.9 (avoids)

Rule 17.9 (avoids)

QAC++

No auto

Prefer using <vector> or <deque> instead of arrays. Rule 8.4.9 (direct)

Rule 17.9 (direct)

QAC++

No auto

Item 38 Never write a copy assignment operator that relies on a

check for self-assignment in order to work properly; a copy

assignment operator that uses the create-a-temporary-and-

swap idiom is automatically both strongly exception-safe

and safe for self-assignment.

Rule 3.1.5 (direct) QAC++

It’s all right to use a self-assignment check as an

optimisation to avoid needless work.

Rule 3.1.5 (direct)

Programmer Skill

QAC++

Item 39 Avoid writing conversion operators. Avoid non-explicit

constructors.

Rule 3.1.10 (direct)

Rule 3.1.11 (direct)

Rule 3.2.3 (avoid)

QAC++

QAC++

QAC++

Item 40 Avoid the “dusty corners” of a language; use the simplest

techniques that are effective.

Use of a Subset

Software Engineering

Programmer Skill

Maintenance

QAC++ partial

PC-Lint partial

Item 41 Avoid unnecessarily terse or clever code, even if it’s

perfectly clear to you when you first write it.

Maintenance No auto

Prefer providing a nonthrowing Swap() and implement copy

assignment in terms of copy construction.

Rule 3.1.4 (direct) QAC++

Page 118: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

6-4

Exceptional C++ Item Control Enforced

Item 42 This is always initialisation ; it is never assignment, and so it

never calls T::operator=(). Yes, I know there’s an “=”

character is there, but don’t let that throw you. That’s just a

syntax holdover from C, not an assignment operation.

Rule 3.1.2 (avoids)

Programmer Skill

QAC++

Prefer using the form “T t(u);” instead of “T t = u;” where

possible. The former usually works wherever the latter

works, and has advantages – for example, it can take

multiple parameters.

Rule 3.1.2 (direct)

Programmer Skill

QAC++

Item 43 Avoid const pass-by-value parameters in function

declarations. Still make the parameter const in the same

function’s definition if it won’t be modified.

Rule 11.4 (avoids)

Rule 11.5 (direct)

QAC++

PC-Lint partial

When using return-by-value for non-builtin return types,

prefer returning a const value.

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

QAC++

QAC++

Item 44 Prefer new style casts. Rule 7.1 (direct) QAC++

Avoid casting away const. Rule 7.4 (direct) QAC++

Avoid downcasts. Rule 3.3.3 (direct) QAC++

Item 46 Prefer to pass objects by reference instead of by value, using

const whenever possible.

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

Rule 11.4 (direct)

Rule 11.5 (direct)

QAC++

QAC++

QAC++

PC-Lint partial

Item 47 Avoid using global or static objects. If you must use a global

or static object, always be very careful about the order of

initialisation rules.

Rule 8.2.2 (direct) QAC++

Always list base classes in a constructor’s initialisation list

in the same order in which they appear in the class

definition.

Rule 3.2.2 (direct) QAC++

Always list the data members in a constructor’s initialisation

list in the same order in which they appear in the class

definition.

Rule 3.2.2 (direct) QAC++

Never write code that depends on the order of evaluation of

function arguments.

Rule 10.3 (direct) QAC++

Table 6-1: HICPP Coverage of Exceptional C++ Items

Page 119: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-1

Appendix 7 – HICPP Coverage of OOTiA Guidelines

The following table details the HICPP coverage of the guidelines presented in [OOT04].

OOTiA Guideline Control Enforced

3.3 Single Inheritance and Dynamic Dispatch

3.3.4 Inheritance with Overriding

Simple overriding rule: An operation may redefine an inherited

operation, and a method may implement an operation so long as changes

to its signature guarantee substitutability.

Software Engineering –

Object Oriented Design

Rule 3.3.10 (direct) QAC++ partial

PC-Lint partial

Accidental override rule: To ensure that overriding is always

intentional rather than accidental, design and code inspections should

consider whether locally defined features are intended to override

inherited features with a matching signature.

Software Engineering –

Object Oriented Design

Simple dispatch rule: When an operation is invoked on an object, a

method associated with the operation in its run time class should be

executed. This rule applies to all calls except explicit calls to superclass

methods, which should be addressed as described by the Method

Extension guidelines.

C++ Single Dispatch

Model

Complete initialisation rule: Each attribute must be initialised to a

value consistent with the class invariant by the class.

Rule 3.2.1 (direct)

Rule 8.4.3 (direct)

QAC++

QAC++

Initialisation dispatch rule: No overridden method should be called

during the initialisation (construction) of an object.

Rule 3.3.13 (direct) QAC++

Dispatch time rule: All dispatch times should be bounded and

deterministic.

Software Engineering –

Analysis and

Verification

Object code traceability rule: Everywhere concerns about source code

to object code traceability and timing analysis dictate, the compiler

vendor may be asked to provide evidence of deterministic, bounded

mapping of the dispatched call. If the evidence is not available from the

compiler vendor, it may be necessary to examine the structure of the

compiler-generated code and data structures (e.g. method tables) at the

point of call.

Software Engineering –

Analysis and

Verification

3.3.5 Method Extension

Method extension rule: When extending the functionality of an

inherited method, the subclass method should explicitly call the

superclass version of the same method.

Software Engineering –

Object Oriented Design

3.3.6 Sub-typing

Minimum compatibility rule: At a minimum, superclass/subclass

compatibility should be verified with respect to all classes involved in

the polymorphic assignment of different subclass instances to the same

variable or parameter during the execution of the system.

Software Engineering -

Verification

Substitutability compliance rule: Any approach used to verify

superclass/subclass compatibility should be consistent with the

principles of behavioural subtyping defined by Liskov and Wing.

Software Engineering –

Verification

3.3.7 Formal Sub-typing

Explicit pre/post-condition/invariant rule: To ensure that all classes

define their interfaces as contracts, all pre/postconditions and invariants

for operations and methods must be explicitly stated and all errors

returned by them must be specified. Unless the program is to be

subjected to automated format analysis, this includes pre/postconditions,

invariants, and error lists that are considered to be trivial (e.g.,

conditions whose value is true, and error lists that are empty).

Software Engineering –

Analysis and

Verification

Page 120: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-2

OOTiA Guideline Control Enforced

Frame condition rule: Unless the language provides a separate

mechanism for indicating which variables may and may not change,

ideally each postcondition should also include a ‘frame condition’ which

indicates which variables are guaranteed not to change as a result of

executing the operation/method.

Rule 3.1.8 (direct)

Rule 7.4 (avoids)

Rule 8.4.11 (direct)

Rule 11.5 (direct)

Software Engineering –

Object Oriented Design,

Analysis and

Verification

QAC++

QAC++

QAC++ partial

PC-Lint partial

3.3.8 Unit Level Testing Suitability

Inherited test case rule: Every test case appearing in the set of test

cases associated with a class should appear in the set of test cases

associated with each of its subclasses.

Software Engineering -

Verification

Separate context rule: If dynamic dispatch is involved in the execution

of a method, the method should be separately tested in the context of

every concrete class in which it appears, irrespective of whether it is

defined by the class or inherited by it, provided that all such tests take

account of the method precondition(s) involved, taking account of any

dynamic binding involved in evaluating the precondition. An exception

is made for methods that are guaranteed not to directly or indirectly

invoke a method that is dynamically bound with respect to the current

object, for example, simple get and set methods that only assign a value

to, or return the value of an attribute or association. Such methods need

only be tested once, in the context of the defining class.

Software Engineering -

Verification

3.3.9 System Level Testing of Substitutability Using Assertions

Pre-condition assertion rule: An assertion to check the operation’s

precondition should appear before the body of all methods that

implement a public operation. In accordance with substitutability, this

precondition may only be weakened or the same in overridden versions

of the operation.

Software Engineering –

Design and Analysis

Post-condition assertion rule: An assertion to check the operation’s

postcondition should appear after the body of all methods that

implement a public operation. In accordance with substitutability, this

postcondition may only be strengthened or the same in overridden

versions of the operation.

Software Engineering –

Design and Analysis

Invariant assertion rule: An assertion to check the operation’s

invariant should be a part of the precondition check and the

postcondition check of all public operations. In accordance with

substitutability, the invariant may only be strengthened or the same in all

subclasses of a class.

Software Engineering –

Design and Analysis

Instrumented/un-instrumented testing rule: A test case run against an

instrumented version of the code should be considered to pass only if all

assertion checks associated with substitutability hold during its

execution. A test case run against an uninstrumented version of the code

should be considered to pass only if it produces the same result that it

did when run against an instrumented version of the same code.

Software Engineering –

Analysis

3.3.10 System Level Testing of Substitutability Using Specialised

Test Cases

Generalised test case rule: First construct a set of system level test

cases to meet the required DO-178B coverage criteria while considering

only the declared classes of objects and object references. The run time

classes of objects and dynamic dispatch should be ignored other than to

mark test cases that include dispatching calls as polymorphic.

Software Engineering -

Verification

Specialised test case rule: Next create a set of specialised test cases for

each polymorphic test case that are explicitly designed to test for

substitutability. The set of test cases generated from a given

polymorphic test case should be designed to drive dynamic dispatch

down different paths with regard to the selection of subclass methods.

The initial state and resulting state associated with each specialised test

case should be compatible (in terms of substitutability) with the more

general test case from which it was derived.

Software Engineering -

Verification

Page 121: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-3

OOTiA Guideline Control Enforced

Min substitutability coverage rule: By this test case coverage criteria,

the full set of specialised test cases must exercise dynamic dispatch to

subclass methods to the extent required to meet the structural coverage

criteria of DO-178B.

Software Engineering -

Verification

Max substitutability coverage rule: By this test case coverage criteria,

the set of specialised test cases derived from each polymorphic test case

must exercise all reachable subclass methods at each point of call

involving dynamic dispatch.

Software Engineering -

Verification

Mid substitutability coverage rule: By this test case coverage criteria,

the full set of specialised test cases must meet the criteria set by the Min

Substitutability coverage rule. Additional specialised test cases,

however, are introduced to test specifically for the types of problems

raised by issues 20, 21, 22, 26, and 40 identified in Volume 2, Appendix

B of this Handbook.

Software Engineering -

Verification

3.3.11 Class Coupling

Client data abstraction rule:

• Clients should access the data representation of the class only

through its public operations.

• All attributes should be hidden (private or protected), and all

strategies associated with the choice of data representation should

be abstracted by its set of public operations.

• All hardware registers should be hidden (private or protected),

and all strategies associated with the use of a particular hardware

device should be abstracted by its set of public operations.

Rule 3.4.1 (direct)

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

Rule 3.4.4 (direct)

Rule 8.3.3 (direct)

Software Engineering –

Design and Analysis

QAC++

QAC++

QAC++

QAC++

QAC++

Invariant rule: The invariant for the class should be:

• An implicit or explicit part of the postcondition of every class

constructor,

• An implicit or explicit part of the precondition of the class

destructor (if any),

• An implicit or explicit part of the precondition and postcondition of

every other publicly accessible operation.

Software Engineering –

Design and Analysis

Subclass data abstraction rule:

• A subclass should access the data representation of its superclass

only through the superclass’ public and protected operations.

• All attributes should be hidden (private), and all strategies

associated with the choice of data representation should be

abstracted by its set of public and protected operations.

• All hardware registers should be hidden (private), and all strategies

associated with the use of a particular hardware device should be

abstracted by its set of public and protected operations.

• The class invariant should also be an implicit or explicit part of the

precondition and postcondition of each protected method of a class,

and part of the postcondition of every protected constructor.

Rule 3.4.1 (direct)

Rule 3.4.2 (direct)

Rule 3.4.3 (direct)

Rule 3.4.4 (direct)

Rule 8.3.3 (direct)

Software Engineering –

Design and Analysis

QAC++

QAC++

QAC++

QAC++

QAC++

3.3.12 Deep Hierarchy

Six deep rule: Any class hierarchy with a depth greater than six

warrants a careful review that specifically addresses the above issues

and weighs this against the need to isolate various proposed changes.

When extending an existing framework, depth should be measured from

the point at which the framework is first subclassed. When developing

an application specific class hierarchy, depth should be measured from

the root. In languages in which all classes implicitly inherit from a

common root class, this class should not be included in the count.

Rule 3.3.7 (avoids)

Rule 3.3.15 (avoids)

Rule 3.4.6 (avoids)

Guideline 3.4.7 (avoids)

Software Engineering –

Object Oriented Design

No auto

QAC++

No auto

No auto

3.4 Multiple Inheritance

3.4.4 Multiple Interface Inheritance

Repeated interface inheritance rule: When the same operation

declaration is inherited by an interface via more than one path through

the interface hierarchy without redeclaration or renaming, this should

result in a single operation in the subinterface.

Rule 3.3.1 (direct)

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

No auto

Page 122: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-4

OOTiA Guideline Control Enforced

Interface redefinition rule: When a subinterface inherits different

definitions of the same operation (as a result of redefinition along

separate paths), the definitions must be combined by explicitly defining

an operation in the subinterface that follows the Simple overriding rule

(section 3.3.4.3) with respect to each parent interface.

Rule 3.3.1 (direct)

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

No auto

Independent interface definition rule: When more than one parent

independently defines an operation with the same signature, the user

must explicitly decide whether they represent the same operation or

whether this represents an error. Such decisions should be recorded as

explicit annotations to the source code. If the operations are not intended

to be the same, one of them should be renamed. If the operations are

intended to be the same, any preconditions and postconditions should

also be the same.

Rule 3.3.1 (direct)

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

QAC++

No auto

Compile time constant rule: All of the above rules apply to compile

time constants as well as operations. Constants whose value involves

run-time computation should not be permitted in interfaces.

New Rule (9)

3.4.5 Multiple Implementation Inheritance

Repeated interface inheritance rule: When the same feature (method

or attribute) is inherited by a class via more than one path through the

interface hierarchy, this should result in a single feature in the subclass.

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Interface redefinition rule: When a subclass inherits different

definitions of the same method (as a result of redefinition along separate

paths), the definitions must be combined by explicitly defining a method

in the subclass that follows the Simple overriding rule: (section 3.3.4.3)

with respect to each parent class.

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Independent interface definition rule: When more than one parent

independently defines a method with the same signature, the user must

explicitly decide whether they represent the same method or whether

this represents an error. If they are intended to be different, renaming

should be used to distinguish them. Otherwise, the definitions must be

combined by explicitly defining a method in the subclass that follows

the Simple overriding rule: (section 3.3.4.3) with respect to each parent

class.

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

3.4.7 Combination of Distinct Abstractions

No diamond rule: Repeated inheritance is not permitted, i.e. no

subclass may inherit from the same superclass via more than one path.

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Independent implementation definition rule: When more than one

parent independently defines a method with the same signature, the user

must explicitly decide whether they represent the same method or

whether this represents an error. If they are intended to be different,

renaming should be used to distinguish them. Otherwise, the definitions

must be combined by explicitly defining a method in the subclass that

follows the Simple overriding rule with respect to each parent class.

(Identical to rule of same name in the section on Multiple

Implementation Inheritance)

Rule 3.3.15 (direct)

Rule 3.4.6 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

3.4.8 Top Heavy Hierarchy

Three parents rule: Any class near the top of the hierarchy with three

or more parents warrants careful review.

Rule 3.3.7 (avoids)

Rule 3.3.15 (avoids)

Rule 3.4.6 (avoids)

Guideline 3.4.7 (avoids)

Software Engineering –

Object Oriented Design

No auto

QAC++

No auto

No auto

Page 123: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-5

OOTiA Guideline Control Enforced

Top heavy composition rule : Any class near the top of the hierarchy

that inherits more than 20 features from each of two or more parent

classes warrants careful review.

Rule 3.3.7 (avoids)

Rule 3.3.15 (avoids)

Rule 3.4.6 (avoids)

Guideline 3.4.7 (avoids)

Software Engineering –

Object Oriented Design

No auto

QAC++

No auto

No auto

Top to bottom rule: Any class hierarchy that contains more classes near

the top of the hierarchy than near the bottom warrants careful review.

Rule 3.3.7 (avoids)

Rule 3.3.15 (avoids)

Rule 3.4.6 (avoids)

Guideline 3.4.7 (avoids)

Software Engineering –

Object Oriented Design

No auto

QAC++

No auto

No auto

3.5 Templates

3.5.3 Source Code Review

A template must be reviewed with respect to the actual parameters to

determine if the source code is verifiable.

Software Engineering -

Verification

3.5.4 Requirements-based Test Development, Review and Change

Each instance of a template with a unique set of arguments should be

tested.

Software Engineering -

Verification

3.5.5 Structural Coverage for Templates

Templates should be analysed for complexity and complex templates

should be avoided. Nested templates and templates used with other

language constructs should be analysed for complexity and justified.

Guideline 16.4 (direct)

Software Engineering –

Analysis and

Verification

No auto

Code sharing is not widely used. In general, code sharing should be

avoided.

Rule 3.3.1 (direct)

Guideline 16.4 (direct)

Software Engineering –

Object Oriented Design

QAC++

No auto

Data and control coupling associated with templates should be evaluated

with respect to the actual parameters.

Software Engineering –

Analysis and

Verification

3.6 Inlining

3.6.3 Inlining and Structural Coverage

Inlining should consist of simple expression only, which is almost

always one line of code. Virtual methods and methods that access other

class methods should not be inlined.

Rule 3.1.6 (direct)

Rule 3.1.7 (direct)

Rule 11.8 (direct)

QAC++

QAC++

QAC++

The structural coverage of the inlined method should be evaluated at the

point of each expansion.

Rule 3.1.6 (avoids)

Guideline 3.1.7 (avoids)

Rule 11.8 (avoids)

Software Engineering –

Verification

QAC++

QAC++

QAC++

For data coupling and control coupling, the verification approach should

address the inlining of code including worst case memory usage

analysis, stack usage analysis, timing analysis, call tree analysis, and

data set/use analysis.

Rule 3.1.6 (avoids)

Guideline 3.1.7 (avoids)

Rule 11.8 (avoids)

Software Engineering –

Analysis and

Verification

QAC++

QAC++

QAC++

3.6.4 Source Code Review of Inlined Code

Review of the inlined method against the low level requirements is

sufficient to verify the behaviour of all expansions.

Rule 3.1.6 (avoids)

Guideline 3.1.7 (avoids)

Rule 11.8 (avoids)

Software Engineering –

Requirements and

Analysis

QAC++

QAC++

QAC++

Page 124: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-6

OOTiA Guideline Control Enforced

3.7 Type Conversion

3.7.4 Source Code Review, Checklist, and Coding Standards

Conversion rule: To help ensure intended function and verification, all

checked and unchecked conversions should be justified or should be

explicit, use the most restrictive conversion available, be conspicuously

marked (identified) in the program source code, and be permitted only

after thorough review and analysis of potential adverse effects.

Rule 3.2.3 (direct)

Rule 7.1 (direct)

Guideline 7.2 (direct)

Rule 7.3 (direct)

Rule 7.4 (direct)

Rule 7.5 (direct)

Rule 7.6 (direct)

Rule 7.7 (direct)

Rule 7.8 (direct)

QAC++

QAC++

QAC++

QAC++

QAC++

QAC++

QAC++

QAC++

QAC++

3.7.5 Loss of Precision in Type Conversions

Loss of information rule: To help ensure correctness, any conversions

that may result in loss of data or data accuracy and precision should be

justified or should: - be explicit, - use the most restrictive conversion

available, - be conspicuously marked (identified) in the program source

code, and only be permitted after thorough review and analysis of

potential adverse effects.

Rule 3.2.3 (direct)

Rule 7.1 (direct)

Guideline 7.2 (direct)

Rule 7.6 (direct)

Rule 7.7 (direct)

Rule 7.8 (direct)

QAC++

QAC++

QAC++

QAC++

QAC++

QAC++

3.7.6 Type Conversions of Reference and Pointers

Super-type rule: To help ensure intended function and verification, all

implicit type conversions involving references/pointers to class instances

should be justified or should only represent a conversion from a subtype

to one of its supertypes.

Rule 3.3.3 (direct)

Rule 7.5 (direct)

QAC++

QAC++

3.7.7 Language Specific Guidelines

All implicit conversions should be checked for potential loss of

precision or loss of data. Specifically the following should be justified:

From integer types to the floating point types (potential loss of

precision)

Rule 10.14 (direct)

Rule 10.15 (direct)

QAC++

QAC++

From a floating point type to an integer type (potential loss of data) Rule 7.6 (direct)

Rule 10.14 (direct)

QAC++

QAC++

From a more precise numeric type to a less precise version of the same

numeric type (potential loss of data and precision)

Rule 10.13 (direct)

Rule 10.15 (direct)

Rule 10.21 (direct)

QAC++

QAC++

QAC++

Implicit conversions between logically unrelated types should be

justified. Unless the single argument constructor was created with the

expressed purpose of permitting implicit conversion between the

argument type and the class type, the constructor should be declared

with the explicit keyword.

Rule 3.2.3 (direct) QAC++

3.8 Overloading and Method Resolution

3.8.3 Code Review Method

Overloaded method rule: Overloaded operations or methods should

form "families" that use the same semantics, share the same name, have

the same purpose, and that are differentiated by the types of their formal

parameters.

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

Software Engineering –

Object Oriented Design

No auto

QAC++

Overloaded operator rule: Overloaded operators should obey the

"natural" meaning and follow conventions of the language. For example,

a C++ operator "+=" should have the same meaning as "+" and "=".

Arithmetic operators should be overloaded using conventional notation

whenever possible.

Rule 3.5.2 (direct)

Rule 3.5.3 (direct)

No auto

QAC++

Overloading in general: When calls are overloaded, reviewers should

know exactly what is being called. Overloading of special language

constructs must be justified.

Rule 3.5.2 (avoids)

Rule 3.5.3 (avoids)

Software Engineering –

Object Oriented Design

and Analysis

No auto

QAC++

Page 125: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

7-7

OOTiA Guideline Control Enforced

3.8.4 Implicit Conversion

The software user of any family of overloaded operators and methods

whose arguments (signatures) are implicitly convertible should perform

the call using arguments that do not need to be converted and perform

analysis appropriate to the level of the software to ensure the proper

method is being called.

Rule 3.1.10 (avoids)

Rule 3.1.11 (avoids)

Rule 3.2.3 (avoids)

Rule 3.5.2 (avoids)

Rule 7.8 (avoids)

Software Engineering –

Object Oriented Design

and Analysis

QAC++

QAC++

QAC++

No auto

QAC++

3.9 Dead and Deactivated Code and Reuse

3.9.3 Reuse of Software Components

Developer’s intent rule: All code must be exercised by requirements-

based tests (the requirements may be derived). Code not associated with

requirements should be carefully evaluated and either removed (if it is

dead code) or requirements should be developed for the code. Code

which exists due to derived requirements needs to be explicitly

identified by the developer and the associated requirements must be

noted as “derived” for inclusion in the SSA process by the integrator.

Software Engineering -

Verification

Cantata C++

facilitates this

testing

All code verified rule: All code verified rule: All code executed within

any aircraft or engine configuration must be verified per applicable DO-

178B objectives, even if it can be demonstrated that a particular piece of

code can never be activated in a specific system. Note that requirements

will be needed for all deactivated code associated with the various

aircraft or engine configurations (either derived requirements or explicit,

option-selectable requirements specified by the integrator).

Software Engineering –

Requirements and

Verification

Cantata C++

QAC++

3.9.5 Certification Credit for Reused but Modified Class Hierarchy

Flattened class re-verification rule: Flattened class re-verification rule:

When a change to an element of a class occurs, re-verification of all

subclasses whose flattened form contains the changed element is

recommended.

Software Engineering -

Verification

No auto

3.9.7 Service History Credit and Deactivated Code

Service history rule: Service history credit may only be given for

activated code and deactivation mechanisms that have been actually

executed. The target environment, certification basis, and SSA will need

to be considered in this process.

Software Engineering -

Verification

No auto

Table 7-1: HICPP Coverage of OOTiA Guidelines

Page 126: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

8-1

Appendix 8 – Unspecified Behaviour (C++ Language)

The following table details unspecified behaviour in the C++ language and the applicable controls

that can be put in place to mitigate them. The behaviours have been extracted directly from [BSI03].

Page Item / Description Control Enforced

45 3 Basic Concepts

3.6.2 Initialisation of Non-local Objects (para 2)

The following example illustrates the point.

inline double fd() { return 1.0; }extern double d1;double d2 = d1; //unspecified

//may be statically initialised to0.0 or

//dynamically initialised to 1.0double d2 = fd(); //may be initialised statically to1.0

It is unspecified whether the value of d1 used will be the value of the fully

initialised d2 (because d2 was statically initialised) or will be the value of d2

merely zero-initialised. This is because objects with static storage duration

shall be zero-initialised before any other initialisation takes place. Also

objects with static storage duration defined in namespace scope in the same

translation unit and dynamically initialised shall be initialised in the order in

which they are defined in the translation unit. Thus it may not be possible to

guarantee that d1 is initialised before d2.

Rule 8.2.2 (direct)

Guideline 8.3.2

(direct)

Software

Engineering -

Design

QAC++

PC-Lint

partial

48 3.7.3.1 Allocation Functions (para 2)

The order, contiguity, and initial value of storage allocated by successive

calls to an allocation function is unspecified.

Rule 13.6 (avoids) QAC++

partial

65 5 Expressions (para 4) – Order of Evaluation

The order of evaluation of operands of individual operators and sub-

expressions of individual expressions, and the order in which side effects

take place is unspecified. The precedence of operators is not directly

specified, but it can be derived from the syntax.

i = v[i++]; //the behaviour is unspecifiedi = 7, i++, i++; //i becomes 9

i = ++i + 1; //the behaviour is unspecifiedi = i + 1; // the value of i is incremented

Rule 3.5.1 (avoids)

Rule 10.3 (direct)

Rule 10.9 (direct)

QAC++

QAC++

QAC++

70 5.2.2 Function Call (para 8) – Order of Argument Evaluation

The order of evaluation of arguments is unspecified. All side effects of

argument expression evaluations take effect before the function is entered.

The order of evaluation of the postfix expression and the argument

expression list is unspecified.

Rule 3.5.1 (avoids)

Rule 10.3 (direct)

QAC++

QAC++

72 5.2.8 Type Identification (para 1)

The result of a typeid expression is an lvalue of static type const

std::type_info and dynamic type const std::type_info or const

name where name is an implementation-defined class derived from

std::type_info which preserves the behaviour described in 18.5.1. The

lifetime of the object referred to by lvalue extends to the end of the program.

Whether or not the destructor is called for the type_info object at the end

of the program is unspecified.

New Rule (5) QAC++

75 5.2.9 Static Cast (para 7)

A value of integral or enumeration type can be explicitly converted to an

enumeration type. The value is unchanged if the original value is within the

range of enumeration values. Otherwise the resulting enumeration value is

unspecified.

Rule 15.4 (direct)

Guideline 7.2

(avoids)

QAC++

QAC++

Page 127: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

8-2

Page Item / Description Control Enforced

76 5.2.10 Reinterpret Cast (para 6, 7, 9)

Except that converting an rvalue of type “pointer to T1” to the type “pointer

to T2” (where T1 and T2 are function types or objects) and back to its

original type yields the original pointer value, the result of such a conversion

is unspecified.

Except that converting an rvalue of type “pointer to T1” to the type “pointer

to T2” (where T1 and T2 are object types and where the alignment

requirements of T2 are no stricter than those of T1) and back to its original

type yields the original pointer value, the result of such a conversion is

unspecified.

An rvalue of type “pointer to member of X of type T1” can be explicitly

converted to an rvalue of type “pointer to member of Y of type T2” if T1

and T2 are both function types of both object types. The null member

pointer value is converted to the null member pointer value of the

destination type. The result of this conversion is unspecified in all but two

specifically specified cases.

Rule 7.5 (direct)

Guideline 7.2

(avoids)

QAC++

QAC++

83 5.3.4 New (para 21)

Whether the allocation function is called before evaluating the constructor

arguments or after evaluating the constructor arguments but before entering

the constructor is unspecified.

Whether the arguments to a constructor are evaluated if the allocation

function returns the null pointer or exits using the exception is unspecified.

Rule 10.3 (direct)

Rule 3.5.1 (avoids)

New Rule (3)

QAC++

QAC++

No auto

85 5.4 Explicit Type Conversion (para 6)

The operand of a cast using the cast notation can be an rvalue of type

“pointer to incomplete class type”. The destination type of a cast using the

cast notation can be “pointer to incomplete class type”. In such cases, even if

there is an inheritance relationship between the source and destination

classes, whether the static_cast or reinterpret_cast interpretation is

used is unspecified.

Rule 7.5 (avoids)

Guideline 7.2

(avoids)

QAC++

QAC++

89 5.9 Relational Operators (para 2) – Pointer Comparison

If two pointers p and q of the same type point to the same object or function,

or both point one past the end of the same array, or both are null, then p<=q

and p>=q both yield true and p<q and p>q both yield false.

If two pointers p and q of the same type point to different objects that are not

members of the same object or elements of the same array or different

functions, or if only one of them is null, the results of p<q, p>q, p<=q, and

p>=q are unspecified.

If two pointers point to non-static data members of the same object, or to

sub-objects or array elements of such members, recessively, the pointer to

the later declared member compares greater provided the two members are

not separated by an access-specifier label and provided their class is not a

union.

If two pointers point to non-static data members of the same object

separated by an access-specifier label the result is unspecified.

If two pointers point to data members of the same union object, they

compare equal (after conversion to void *, if necessary). If two pointers

point to elements of the same array or one beyond the end of the array, the

pointer to the object with the higher subscript compares higher.

All other pointer comparisons are unspecified.

Rule 5.2 (direct)

Guideline 10.6

(direct)

PC-Lint

partial

No auto

89 5.10 Equality Operators (para 2) – Pointer Comparison

If either pointer is a pointer to a virtual function, then the result is

unspecified.

Rule 3.3.4 (avoids)

Rule 5.2 (direct)

New Rule (7)

QAC++

PC-Lint

partial

No auto

Page 128: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

8-3

Page Item / Description Control Enforced

114 7 Declarations

7.2 Enumeration Declarations (para 4, 9)

If no initialiser is specified for the first enumerator, the type is an

unspecified integral type. Otherwise the type is the same as the type of the

initialising value of the preceding enumerator unless the incremented value

is not representable in that type, in which case the type in an unspecified

integral type sufficient to contain the incremented value.

An expression of arithmetic or enumeration type can be converted to an

enumeration type explicitly. The value is unchanged if it is in the range of

enumeration values of the enumeration type; otherwise the resulting

enumeration value is unspecified.

Rule 13.6 (direct)

Rule 15.4

Guideline 7.2

(direct)

QAC++

partial

PC-Lint

partial

QAC++

QAC++

136 8 Declarators

8.3.2 References (para 3)

It is unspecified whether or not a reference requires storage.

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

143 8.3.6 Default Arguments (para 9)

Default arguments are evaluated each time the function is called. The order

of evaluation of function arguments is unspecified.

Rule 10.3 (direct) QAC++

159 9 Classes

9.2 Class Members (para 12) – Allocation

The order of allocation of non-static data members separated by an access

specifier is unspecified.

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

170 10 Derived Classes (para 3)

The order in which the base class sub-objects are allocated in the most

derived object is unspecified.

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

183 11 Member Access Control

11.1 Access Specifiers (para 2) – Allocation

The order of allocation of data members with separate access-specifier

labels is unspecified.

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

194 12 Special Member Functions (para 15) – Constructors

During the construction of a const object, if the value of the object or any of

its sub-objects is accessed through an lvalue that is not obtained, directly or

indirectly, from the constructor’s this pointer, that value of the object or sub-

object thus obtained is unspecified.

New Rule (2) QAC++

partial

PC-Lint

partial

196 12.2 Temporary Objects (para 5)

class C {public:

C();C(int);Friend C operator+(const C&, const C&);~C();

};C obj1;const C& cr = C(16)+C(23);C obj 2;

A first temporary T1 to hold the result of the expression C(16), a second

temporary T2 to hold the result of expression C(23), and a third temporary

T3 to hold the result of the addition of these two expressions. The temporary

T3 is then bound to the reference cr. It is unspecified whether T1 or T2 is

created first.

Rule 10.3 (direct)

Rule 3.5.1 (avoids)

QAC++

QAC++

215 12.8 Copying Class Objects (para 13)

It is unspecified whether sub-objects representing virtual base classes are

assigned more than once by the implicitly-defined copy assignment

operator.

Rule 3.1.3 (avoids)

Rule 3.1.5 (direct)

Rule 3.1.13

(avoids)

QAC++

QAC++

QAC++

Page 129: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

8-4

Page Item / Description Control Enforced

282 14 Templates

14.7.1 Implicit Instantiation (para 5, 9)

If the overload resolution process can determine the correct function to call

without instantiating a class template definition, it is unspecified whether

instantiation actually takes place.

It is unspecified whether or not an implementation implicitly instantiates a

virtual member function of a class template if the virtual member function

would not otherwise be instantiated.

Rule 16.2 (avoids)

Rule 16.3 (avoids)

No auto

307 15 Exception Handling

15.1 Throwing an Exception (para 4)

When the last handler being executed for the exception exists by any means

other than throw; the temporary object is destroyed and the implementation

may de-allocate the memory for the temporary object; any such de-

allocation is done in an unspecified way.

New Rule (13) No auto

320 16 Preprocessing Directives

16.3.2 The # Operator (para 2)

The order of evaluation of # and # # operators is unspecified.

Rule 10.3 (direct) QAC++

320 16.3.3 The # # Operator (para 3)

The order of evaluation of # # operators is unspecified.

Rule 10.3 (direct) QAC++

Table 8-1: C++ Language Unspecified Behaviour [BSI03]

Page 130: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

9-1

Appendix 9 – Unspecified Behaviour (C++ STL)

The following table details unspecified behaviour in the C++ STL and the applicable controls that

can be put in place to mitigate them. The behaviours have been extracted directly from [BSI03].

Page Item / Description Control Enforced

339 17 Library Introduction

17.4.4.3 Global, or Non-Member Functions (para 1)

It is unspecified whether any global or non-member functions in the C++

Standard Library are defined as inline.

Efficiency

339 17.4.4.4 Member Functions (para 1, 2)

It is unspecified whether any member functions in the C++ Standard Library

are defined as inline.

An implementation can declare additional non-virtual member function

signatures within a class by adding elements with default values to a

member function signature. Hence, taking the address of a member function

has an unspecified type.

Efficiency

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

340 17.4.4.6 Protection within Classes (para 1)

It is unspecified whether a function signature or class in clauses 18 through

27 is a friend of another class in the C++ Standard Library.

Guideline 13.1

(supports)

No auto

340 17.4.4.7 Derived Classes (para 1, 2)

It is unspecified whether a class in the C++ Standard Library is itself derived

from other classes (with names reserved to the implementation).

It is unspecified whether a class described in the C++ Standard Library as

derived from another class is derived from another class directly, or through

other classes (with names reserved to the implementation) that are derived

from the specified base class.

Guideline 13.1

(supports)

No auto

354-

35518 Language Library Support

18.4.1 Storage Allocation and De-allocation

18.4.1.1 Single-Object Forms (para 4, 8, 14)

void* operator new(std::size_t size)throw(std::bad_alloc)void* operator new(std::size_t size, conststd::nothrow_t&) throw();

This call executes a loop. Within the loop the function first attempts to

allocate the requested storage. Whether this attempt involves a call to the

Standard C Library function malloc is unspecified.

void operator delete(void* ptr) throw();void operator delete(void* ptr, const std::nothrow_t&)throw();

It is unspecified under what conditions part or all of such reclaimed storage

is allocated by a subsequent call to operator new or any of calloc, malloc,

or realloc, declared in <cstdlib>.

Guideline 13.1

(supports)

No auto

Page 131: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

9-2

Page Item / Description Control Enforced

355-

35618.4.1 Storage Allocation and De-allocation

18.4.1.2 Array Forms (para 3,7,13)

void* operator new[](std::size_t size)throw(std::bad_alloc)void* operator new[](std::size_t size, conststd::nothrow_t&) throw();

This call executes a loop. Within the loop the function first attempts to

allocate the requested storage. Whether this attempt involves a call to the

Standard C Library function malloc is unspecified.

void operator delete[](void* ptr) throw();void operator delete[](void* ptr, const std::nothrow_t&)throw();

It is unspecified under what conditions part or all of such reclaimed storage

is allocated by a subsequent call to operator new or any of calloc, malloc,

or realloc, declared in <cstdlib>.

Guideline 13.1

(supports)

No auto

358 18.5 Type Identification

18.5.1 Class type_info (para 1)

The class type_info describes type information generated by the

implementation. Objects of this class effectively store a pointer to a name

for the type, and an encoded value suitable for comparing two types for

equality or collating order. The names, encoding rule and collating sequence

for types are all unspecified and may differ between programs.

Guideline 13.1

(supports)

Software

Engineering –

Object Oriented

Design

QAC++

partial

388 20 General Utilities Library

20.4.1.1 allocator Numbers (para 6, 10)

pointer allocate(size_type n,allocator<void>::const_pointer hint=0);

The storage is obtained by calling ::operator new(size_t), but it is

unspecified when or how often this function is called. The use of hint is

unspecified, but intended as an aid to locality if an implementation so

desires.

void deallocate(pointer p, size_type n);

Uses ::operator delete(void *), but it is unspecified when this

function is called.

Guideline 13.1

(supports)

No auto

396 21 String Library

21.1.1 Character Traits Requirements (para 1)

X::to_char_type(e)

X::eq_int_type(e,X::to_int_type(c)) is true, c; else some

unspecified value.

X::eq_int_type(e,f)

Yields for all c and d, X::eq(c,d) is equal to

X::eq_int_type(X::to_int_type(c), X::to_int_type(d));

otherwise, yields true if e and f are both copies of X::eof(); otherwise

yields false if one of e and f are copies of X::eof() and the other is not;

otherwise the value is unspecified.

Guideline 13.1

(supports)

No auto

407 21.3.1 basic_string Constructors (para 2)

explicit basic_string(const Allocator& a = Allocator());

A post condition of this function is that the element capacity() is an

unspecified value.

Guideline 13.1

(supports)

No auto

Page 132: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

9-3

Page Item / Description Control Enforced

448 22 Localisation Library

22.2.1.5.2 codecvt Virtual Functions (para 3)

result do_out(stateT& state, const internT* from, constinternT* from_end, const internT* from_next, externT* to,externT* to_limit, externT*& to_next) const;

result do_out(stateT& state, const internT* from, constinternT* from_end, const internT* from_next, externT* to,externT* to_limit, externT*& to_next) const;

Its operations on state are unspecified.

Guideline 13.1

(supports)

No auto

464 22.2.5.1 Class Template time_get (para 1)

time_get is used to parse a character sequence, extracting components of a

time or date into a struct tm record. If the sequence being parsed matches the

correct format, the corresponding members of the struct tm argument are set

to the values used to produce the sequence; otherwise either an error is

reported or unspecified values are assigned.

Guideline 13.1

(supports)

No auto

475 22.2.7.1.2 messages Virtual Functions (para 6)

void do_close(catalog cat) const;

Releases unspecified resources associated with cat.

Guideline 13.1

(supports)

No auto

580 25 Algorithms Library

25.3.1.3 partial_sort (para 1)

Places the first middle – first sorted elements from the range [first, last] into

the range [first, middle]. The rest of the elements in the range [middle, last]

are placed in an unspecified order.

Guideline 13.1

(supports)

No auto

592 26 Numerics Library

26.2 Complex Numbers

The effect of instantiating a template complex for any type other than float,

double or long is unspecified.

Guideline 13.1

(supports)

No auto

608 26.3.2.7 valarray Member Functions (para 2)

If the array has length 0, the behaviour is undefined. If the array has length

1, sum() returns the value of element 0. Otherwise, the returned value is

calculated by applying operator+= to a copy of an element of the array

and all other elements of the array in an unspecified order.

Guideline 13.1

(supports)

No auto

633 27 Input/Output Library

27.4.2 Class ios_base (para 3)

static int index, specified the next available unique index for the

integer or pointer arrays maintained for the private use of the program

initialised to an unspecified value.

Guideline 13.1

(supports)

No auto

637 27.4.2.5 ios_base Static Members (para 2, 4)

long& iword(int idx);

If iarray is a null pointer, allocates an array of long of unspecified size and

stores a pointer to its first element in iarray.

Void* & pword(int idx);

If parray is a null pointer, allocates an array of pointers to void of

unspecified size and stores a pointer to its first element in parray.

Guideline 13.1

(supports)

No auto

639 27.4.3.2 fpos Requirements (para 1)

It is unspecified whether these operators are members of fpos, global

operators, or provided in some other way.

Guideline 13.1

(supports)

No auto

Page 133: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

9-4

Page Item / Description Control Enforced

654 27.5.2.4.4 Putback (para 1)

int_type pbackfail(int_type c = traits::eof());

If traits::eq_int_type(c,traits::eof()) return false, then c is

prepended. Whether the input sequence is backed up or modified in any

other way is unspecified.

Guideline 13.1

(supports)

No auto

674,

67527.6.3 Standard Manipulators (para 3, 4, 5, 6, 7, 8)

smanip resetioflags(ios_base::fmtflags mask);smanip setiosflags(iosbase::fmtflags mask);smanip setbase(int base);smanip setprecision(int n);smanip setw(int n);

Returns an object s of unspecified type such that if out is an (instance of)

basic_ostream then the expression out<<s behaves as if f(s) were

called, and if in an (instance of) basic_istream then the expression

in>>s behaves as if f(s) were called.

smanip setfill(char_type c_;

Returns an object s of unspecified type such that if out is (or is derived from)

basic_ostream<charT,traits> and c has charT then the expression

out<<s behaves as if f(s) were called.

Guideline 13.1

(supports)

No auto

678,

68827.7.1.3 Overridden Virtual Functions (para 4)

27.8.1.4 Overridden Virtual Functions (para 7)

int_type pbackfail(int_type c = traits::eof());

Puts back the character designated by c to the input sequence, if possible in

one of three ways. If the function can succeed in more than one of these

ways, it is unspecified which way is chosen.

Guideline 13.1

(supports)

No auto

733 Annex D Compatibility Features

D.7.1.1 strstreambuf Constructors (para 2, 3)

strstreambuf(void* (*)(size_t), void (*)(void*))strstreambuf(charT*,streamsize,charT*)

A post-condition of these functions is that the element alsize is an

unspecified value.

Guideline 13.1

(supports)

No auto

735 D.7.1.3 strstreambuf Overridden Virtual Functions (para 3)

int_type overflow(int_type c = EOF);

The function can alter the number of write positions available as a result of a

call. To make a write position, the function reallocates an array object with a

sufficient number of elements n to hold the current array object, plus at least

one additional write position. How many additional write positions are made

available is otherwise unspecified.

Guideline 13.1

(supports)

Efficiency

No auto

Table 9-1: C++ STL Unspecified Behaviour [BSI03]

Page 134: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-1

Appendix 10 – Undefined Behaviour (C++ Language)

The following table details undefined behaviour in the C++ language and the applicable controls

that can be put in place to mitigate them. The behaviours have been extracted directly from [BSI03].

Page Item / Description Control Enforced

9 2 Lexical Conventions

2.1 Phases of Translation (para 2, 4)

Each instance of a new-line character and an immediately preceding back-

slash character is deleted, splicing physical source lines to form logical

source lines. If, as a result, a character sequence that matches the syntax of

the universal-character-name is produced, the behaviour is undefined. If a

source file that is not empty does not end in a new-line character, or ends in

a new-line character immediately preceded by a back-slash character, the

behaviour is undefined.

Preprocessing directives are executed and macro invocations are expanded.

If a character sequence that matches the syntax of a universal-character-

name is produced by token concatenation, the behaviour is undefined.

Rule 6.4 (direct)

Rule 14.8 (direct)

Rule 14.7 (direct)

QAC++

QAC++

QAC++

11 2.4 Preprocessing Tokens (para 2)

If a ‘ or a “ character matches the last category (single non-whitespace

characters), the behaviour is undefined.

Rule 14.7 (avoids)

Rule 14.17 (avoids)

QAC++

partial

PC-Lint

partial

13 2.8 Header Names (para 2)

If either of the characters ‘ or \, or either of the character sequences /* or //

appear in a q-char-sequence or a h-char-sequence, or the character “ appears

in a h-char-sequence, the behaviour is undefined. Thus, sequences of

characters that resemble escape sequences cause undefined behaviour.

Rule 14.10 (direct)

Rule 14.17 (avoids)

QAC++

16 2.13.1 Integer Literals (para 2) - Type

The type of an integer literal depends on its form, value, and suffix. If it is

decimal and has no suffix, it has the first of these types in which its value

can be represented: int, long int; if the value cannot be represented as a

long int, the behaviour is undefined.

Rule 6.1 (avoids)

Rule 13.6 (direct)

No auto

QAC++

partial

PC-Lint

partial

18 2.13.2 Character Literals (para 3) – Escape Sequence

If the character following a back-slash is not one of those specified, the

behaviour is undefined.

Rule 6.4 (direct) QAC++

19 2.13.4 String Literals (para 2, 3)

The effect of attempting to modify a string literal is undefined.

In translation phase 6, adjacent narrow string literals are concatenated and

adjacent wide string literals are concatenated. If a narrow string literal token

is adjacent to a wide string literal token, the behaviour is undefined.

Rule 13.6 (direct)

Rule 6.5 (direct)

QAC++

partial

PC-Lint

partial

QAC++

23,

243 Basic Concepts

3.2 One Definition Rule (para 5)

If D is a template, and is defined in more than one translation unit, then the

last four requirements from the list above shall apply to names from the

template’s enclosing scope used in the template definition, and also to

dependant names at the point of instantiation. If the definitions of D satisfy

all these requirements, then the program shall behave as if there were a

single definition of D. If the definitions of D do not satisfy these

requirements, then the behaviour is undefined.

Rule 8.1.3 (direct)

Rule 8.3.4 (direct)

Rule 16.2

QAC++

QAC++

PC-Lint

partial

44 3.6.1 Main Function (para 4)

If exit is called to end a program during the destruction of an object with

static storage duration, the program has undefined behaviour.

Rule 5.9 (avoids) QAC++

46 3.6.3 Termination (para 2)

If a function contains a local object of static storage duration that has been

destroyed and the function is called during the destruction of an object with

static duration, the program has undefined behaviour if the flow of control

passes through the definition of the previously destroyed object.

Rule 5.9 (avoids)

Rule 8.2.2 (avoids)

QAC++

QAC++

Page 135: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-2

Page Item / Description Control Enforced

48 3.7.3.1 Allocation Functions (para 2)

The effect of de-referencing a pointer returned as a request for zero size is

undefined.

New Rule (17) QAC++

partial

PC-Lint

partial

49 3.7.3.2 De-allocation Functions (para 4)

If the argument given to a de-allocation function in the standard library is a

pointer that is not the null pointer value, the de-allocation function shall de-

allocate the storage referenced by the pointer, rendering invalid all pointers

referring to any part of the de-allocated storage. The effect of using an

invalid pointer value (including passing it to a de-allocation function) is

undefined.

Rule 12.2 (direct)

Rule 12.8 (avoids)

QAC++

QAC++

partial

PC-Lint

partial

49-

513.8 Object Lifetime (para 4, 5, 6, 8, 9)

A program may end the lifetime of any object by reusing the storage which

the object occupies or by explicitly calling the destructor for an object of a

class type with a non-trivial destructor. For an object of a class type with

non-trivial destructor, the program is not required to call the destructor

explicitly before the storage which the object occupies is reused or released.

However if there is no explicit call to the destructor, the destructor shall not

be implicitly called and any program that depends on the side effects

produced by the destructor has undefined behaviour.

Before the lifetime of an object has started but after the storage which the

object will occupy has been allocated or, after the lifetime of an object has

ended and before the storage which the object occupied is reused or

released, any pointer that refers to the storage location where the object will

be or was located may be used but only in limited ways. If the object will be

or was of a class type with a non-trivial destructor, and the pointer is used as

the operand of a deleted-expression, the program has undefined behaviour.

If the object will be or was of non-POD class type, the program has

undefined behaviour in several cases.

Similarly, before the lifetime of an object has started but after the storage

which the object will occupy has been allocated or, after the lifetime of an

object has ended and before the storage which the object occupied is reused

or released, any lvalue which refers to the original object may be used but

only in limited ways. If an lvalue-to-rvalue conversion is applied to such an

lvalue, the program has undefined behaviour; if the original object will be or

was of a non-POD class type, the program has undefined behaviour in

several cases.

If a program ends the lifetime of an object of type T with static or automatic

storage duration and if T has a non-trivial destructor, the program must

ensure than an object of the original type occupies that same storage location

when the implicit destructor call takes place; otherwise the behaviour of the

program is undefined.

Creating a new object at the storage location that a const object with static or

automatic storage duration occupies or, at the storage location that such a

const object used to occupy before its lifetime ended results in undefined

behaviour.

Rule 12.2 (avoids)

May impact on

multithreaded

applications

May impact on

multithreaded

applications

Rule 8.2.2 (avoids)

Rule 12.2 (avoids)

QAC++

QAC++

QAC++

57 3.10 Lvalues and Rvalues (para 15)

If a program attempts to access the stored value of an object through an

lvalue of other than one of the following (listed) types the behaviour is

undefined.

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

60 4 Standard Conversions

4.1 Lvalue-to-rvalue Conversion (para 1)

An lvalue of a non-function, non-array type T can be converted to an rvalue.

If T is an incomplete type, a program that necessitates this conversion is ill-

formed. If the object to which the lvalue refers is not an object of type T or

is not an object derived from type T, or if the object is un-initialised, a

program that necessitates this conversion has undefined behaviour.

Rule 7.8 (direct)

Guideline 10.7

(direct)

QAC++

QAC++

Page 136: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-3

Page Item / Description Control Enforced

62 4.8 Floating Point Conversions (para 1)

An rvalue of a floating point type can be converted to an rvalue of another

floating point type. If the source value can be exactly represented in the

destination type, the result of the conversion is that exact representation. If

the source value is between two adjacent destination values, the result of the

conversion is an implementation-defined choice of either of those values.

Otherwise, the behaviour is undefined.

Rule 10.15 (direct)

Rule 10.14 (direct)

Guideline 10.7

(direct)

QAC++

QAC++

QAC++

62 4.9 Floating Integral Conversion (para 1)

An rvalue of a floating point type can be converted to an rvalue of an integer

type. The conversion truncates; that is the fractional part is discarded. The

behaviour is undefined if the truncated value cannot be represented in the

destination type.

Rule 7.6 (avoids)

Guideline 10.7

(direct)

QAC++

QAC++

65 5 Expressions (para 4, 5)

If during the evaluation of an expression, the result is not mathematically

defined or not in the range of representable values for its type, the behaviour

is undefined, unless such an expression is a constant expression, in which

case the program is ill-formed.

Between the previous and next sequence point a scaler object shall have its

stored value modified at most once by the evaluation of an expression.

Further, the prior value shall be accessed only to determine the value to be

stored. The requirements of this paragraph shall be met for each allowable

ordering of the sub-expressions of a full expression, otherwise the behaviour

is undefined.

Rule 10.13 (direct)

Rule 10.17 (direct)

Rule 10.18 (direct)

ISO C++ Compiler

QAC++

QAC++

No auto

68,

705.2.2 Function Calls (para 1, 7)

Calling a function through an expression whose function type has a language

linkage that is different from the language linkage of the function type of the

called function’s definition is undefined.

When there is no parameter for a given argument, the argument is passed in

such a way that the receiving function can obtain the value of the argument

by invoking va_arg. The lvalue-to-rvalue, array-to-pointer, and function-to-

pointer standard conversions are performed on the argument expression. If

the argument has a non-POD class type, the behaviour is undefined.

New Guideline

(18)

Rule 10.3 (direct)

Rule 11.6 (avoids)

No auto

QAC++

QAC++

74 5.2.9 Static Cast (para 5, 8, 9)

An lvalue of type “cv1 B”, where B is a class type, can be cast to type

“reference to cv2 D”, where D is a class derived from B, if a valid standard

conversion from “pointer to D” to “pointer to B” exists, cv2 is the same cv-

qualification as, or greater cv-qualification than, cv1, and B is not a virtual

base class of D. The result is an lvalue of type “cv2 D”. If the lvalue of type

“cv1 B” is actually a sub-object of an object of type D, the lvalue refers to

the enclosing object of type D. Otherwise, the result of the cast is undefined.

An rvalue of type “pointer to cv1 B”, where B is class type, can be

converted to an rvalue of type “pointer to cv2 D”, where D is class derived

from B, if a valid standard conversion from “pointer to D” to “pointer to B”

exists. Cv2 is the same cv-qualification as, or greater cv-qualification than,

cv1, and B is not a virtual base class of D. The null pointer value is

converted to the null pointer value of the destination type. If the rvalue of

type “pointer to cv1 B” points to a B that is actually a sub-object of an

object of type D, the resulting pointer points to the enclosing object of type

D. Otherwise, the result of the cast is undefined.

An rvalue of type “pointer to member of D of type cv1 T” can be converted

to an rvalue of type “pointer to member of B of type cv2 D”, where B is a

base class of D, if a valid standard conversion from “pointer to member of B

of type T” to “pointer to member of D of type T” exists, and cv2 is the same

cv-qualification as, or greater cv-qualification than, cv1. The null pointer

value is converted to the null pointer value of the destination type. If class B

contains the original member, or is a base or derived class of the class

containing the original member, the resulting pointer to member points to

the original member. Otherwise, the result of the cast is undefined.

Rule 7.5 (direct)

Guideline 7.2

(avoids)

QAC++

QAC++

Page 137: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-4

Page Item / Description Control Enforced

76 5.2.10 Reinterpret Cast (para 6)

A pointer to a function can be explicitly converted to a pointer to a function

of different type. The effect of calling a function through a pointer to

function type that is not the same as the type used in the definition of the

function is undefined.

Rule 7.5 (direct)

Guideline 7.2

(avoids)

QAC++

QAC++

77 5.2.11 Const Cast (para 7, 12)

Depending on the type of the object, a write operation through the pointer,

lvalue or pointer to data member resulting from a const_cast that casts

away a const qualifier may produce undefined behaviour.

Note: some conversions which involve only changes in cv-qualification

cannot be done using const_cast. For instance, conversions between

pointers to functions are not covered because such conversions lead to

values whose use can cause undefined behaviour.

Rule 7.3 (direct)

Guideline 7.2

(avoids)

QAC++

QAC++

79 5.3.1 Unary Operators (para 4)

The address of an object of incomplete type can be taken, but if the complete

type of that object is a class type that declares operator&() as a member

function, then the behaviour is undefined.

Rule 3.1.13

(avoids)

QAC++

81 5.3.4 New (para 6)

Every constant expression in a direct-new-declarator shall be an integral

constant expression and evaluate to a strictly positive value. The expression

in a direct-new-declarator shall have integral or enumeration type with a

non-negative value. If the value is negative, the effect is undefined.

New Rule (17) QAC++

partial

PC-Lint

partial

83,

845.3.5 Delete (para 2, 3, 5)

In delete object, the value of the operand of delete shall be a pointer to a

non-array object or pointer to a sub-object representing a base class of such

an object. If not, the behaviour is undefined. In delete array, the value of the

operand of delete shall be the pointer value that previously results from a

previous array new expression. If not, the behaviour is undefined.

In delete object, if the static type of the operand is different from its dynamic

type, the static type of the base class of the operand’s dynamic type and the

static type shall have a virtual destructor or the behaviour is undefined. In

delete array, if the dynamic type of the object to be deleted differs from its

static type, the behaviour is undefined.

If the object being deleted has incomplete class type at the point of deletion

and the complete class has a non-trivial destructor or de-allocation function,

the behaviour is undefined.

Rule 12.2 (direct)

Rule 12.3 (direct)

Rule 3.3.2 (direct)

Rule 8.4.9 (avoids)

Rule 3.1.13

(avoids)

QAC++

QAC++

QAC++

QAC++

QAC++

85-

865.5 Pointer to Member Operators (para 4, 6)

If the dynamic type of the object does not contain the member to which the

pointer refers, the behaviour is undefined.

If the result of .* or ->* is a function, then that result can only be used as

the operand for the function call operator ().

(ptr_to_obj->*ptr_to_mfct)(10);

This code calls the member function denoted by ptr_to_mfct for the

object pointer to by ptr_to_obj. The result of an .* expression is an

lvalue only if its first operand is an lvalue and its second operand is a pointer

to data member. The result of an ->* expression is an lvalue only if its

second operand is a pointer to data member. If the second operand is the null

pointer to member value, the behaviour is undefined.

Guideline 8.4.10

(avoids)

QAC++

86 5.6 Multiplicative Operators (para 4)

The binary / operator yields the quotient, and the binary % operator yields

the remainder from the division of the first expression by the second. If the

second operand of / or % is zero the behaviour is undefined.

Rule 10.17 (direct) QAC++

Page 138: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-5

Page Item / Description Control Enforced

87 5.7 Additive Operators (para 5, 6)

When an expression that has integral type is added or subtracted from a

pointer, the result has the type of the pointer operand. If the pointer operand

points to an element of an array object, and the array is large enough, the

result points to an element offset from the original element such that the

difference of the subscripts of the resulting and original array elements

equals the integral expression. If both the pointer operand and the result

point to elements of the same array object, or one past the last element of the

array object, the evaluation shall not produce an overflow; otherwise the

behaviour is undefined.

When two pointers to elements of the same array are subtracted, the result is

the difference of the subscripts of the two array elements. If the result does

not fit within the space provided, the behaviour is undefined. Unless both

pointers point to elements of the same array object, or one past the last

element of the array object, the behaviour is undefined.

Rule 10.2 (direct)

Rule 8.4.9 (avoids)

QAC++

No auto

88 5.8 Shift Operators (para 1)

The behaviour is undefined if the right operand is negative, or greater than

or equal to the length in bits of the promoted left operand.

Rule 10.11 (direct)

Rule 10.12 (direct)

QAC++

QAC++

92 5.17 Assignment Operators (para 8)

If the value being stored in an object is accessed from another object that

overlaps in any way the storage of the first object, then the overlap shall be

exact and the two objects shall have the same type, otherwise the behaviour

is undefined.

Rule 13.6 (direct) QAC++

partial

PC-Lint

partial

100 6 Statements

6.6.3 The return Statement (para 2)

Flowing off the end of a function is equivalent to a return with no value; this

results in undefined behaviour in a value returning function.

Rule 5.10 (direct) QAC++

101 6.7 Declaration Statement (para 4)

If control re-enters the declaration (recursively) while the object is being

initialised, the behaviour is undefined.

New Rule (6) QAC++

Partial

109-

1107 Declarations

7.1.5.1 The cv-qualifiers (para 4, 7)

Except that any class member declared mutable can be modified, any

attempt to modify a const object during its lifetime results in undefined

behaviour.

If an attempt is made to refer to an object defined with a volatile-qualified

type through the use of an lvalue with a non-volatile-qualified type, the

program behaviour is undefined.

Rule 7.4 (direct)

Rule 7.3 (direct)

QAC++

QAC++

137 8 Declarators

8.3.2 References (para 4)

A null reference cannot exist in a well defined program, because the only

way to create such a reference would be to bind it to the “object” obtained

by dereferencing a null pointer, which causes undefined behaviour.

New Rule (10) QAC++

partial

PC-Lint

partial

161 9 Classes

9.3.1 Non-static Member Functions (para 1)

If a nonstatic member function of a class X is called for an object that is not

of type X, or if a type derived from X, the behaviour is undefined.

Rule 7.1 (avoids)

Guideline 7.2

(avoids)

QAC++

QAC++

179 10 Derived Classes

10.4 Abstract Classes (para 6)

Member functions can be called from a constructor (or destructor) of an

abstract class; the effect of making a virtual call to a pure virtual function

directly or indirectly for the object being created (or destroyed) from such a

constructor (or destructor) is undefined.

Rule 3.3.13 (direct) QAC++

Page 139: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-6

Page Item / Description Control Enforced

201,

20212 Special Member Functions

12.4 Destructors (para 12, 14)

The invocation of a destructor is subject to the usual rules for member

functions, that is, if the object is not of the destructor’s class type and not of

a class derived from the destructor’s class type, the program has undefined

behaviour (except that invoking delete on a null pointer has no effect).

Once a destructor is invoked for an object, the object no longer exists; the

behaviour is undefined if the destructor is invoked for an object whose

lifetime has ended.

Rule 7.1 (avoids)

Guideline 7.2

(avoids)

Rule 12.8 (avoids)

QAC++

QAC++

No auto

208 12.6.2 Initialising Bases and Members (para 8)

Member functions can be called for an object under construction. Similarly,

an object under construction can be the operand of the type_id operator or

of a dynamic_cast. However, if these operations are performed in a ctor-

initialiser (or in a function called directly or indirectly from a ctor-initialiser)

before all mem-initialisers for base classes have completed, the result of the

operation is undefined.

New Rule (5)

New Rule (2)

Guideline 7.2

(avoids)

QAC++

No auto

QAC++

209-

21112.7 Construction and Destruction (para 1, 2, 3, 4, 5)

For an object of non-POD class type, before the constructor begins

execution and after the destructor finishes execution, referring to any non-

static member or base class of the object results in undefined behaviour.

To explicitly or implicitly convert a pointer (lvalue) referring to an object of

class X to a pointer (reference) to a direct or indirect case class B of X, the

construction of X and the construction of all of its direct or indirect bases

that directly or indirectly derive from B shall have started and the

destruction of these classes shall not have completed, otherwise the

conversion results in undefined behaviour.

To form a pointer to (or access the value of) a direct non-static member of

an object obj, the construction of obj shall have started and its destruction

shall not have completed, otherwise the computation of the pointer value (or

accessing the member value) results in undefined behaviour.

If the virtual function call uses an explicit class member access and the

object-expression refers to the object under construction or destruction but

its type is neither the constructor or destructor’s own class or one of its

bases, the result of the call is undefined.

If the operand of type_id refers to the object under construction or

destruction and the static type of the operand is neither the constructor or

destructor’s class nor one of its bases, the result of typeid is undefined.

If the operand of the dynamic_cast refers to the object under construction

or destruction and the static type of the operand is not a pointer to or object

of the constructor or destructor’s own class or one of its bases, the

dynamic_cast results in undefined behaviour.

Rule 12.8 (avoids)

Rule 7.1 (direct)

Guideline 7.2

(avoids)

No auto

QAC++

QAC++

279 14 Templates

14.6.4.2 Candidate Functions (para 1)

If the call would be ill-formed or would find a better match had the lookup

within the associated namespaces considered all the function declarations

with external linkage introduced in those namespaces in all translations

units, not just considering those declarations found in the template definition

and template instantiation contexts, then the program has undefined

behaviour.

Rule 8.3.4 (direct)

Guideline 8.3.2

(direct)

Rule 14.13

QAC++

partial

PC-Lint

partial

No auto

283 14.7.1 Implicit Instantiation (para 14)

The result of an infinite recursion in instantiation is undefined.

Rule 13.3 (avoids) No auto

Page 140: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

10-7

Page Item / Description Control Enforced

309,

31015 Exception Handling

15.3 Handling an Exception (para 10, 16)

Referring to any non-static member or base class of an object in the handler

for a function-try-block of a constructor or destructor for that object results

in undefined behaviour.

Flowing off the end of a function-try-block is equivalent to a return with no

value; this results in undefined behaviour in a value-returning function.

New Rule (14)

New Rule (14) QAC++

316 16 Preprocessing Directives

16.1 Conditional Inclusion (para 4)

If the token defined is generated as a result of this replacement process or

use of the defined unary operator does not match one of the two specified

forms prior to macro replacement, the behaviour is undefined.

Rule 14.5 (avoids) QAC++

318 16.2 Source File Inclusion (para 4)

If the directive resulting after all replacements does not match one of the two

previous forms, the behaviour is undefined.

Rule 14.9 (direct) QAC++

319 16.3 Macro Replacement (para 10)

If (before argument substitution) any argument consists of no pre-processing

tokens, the behaviour is undefined.

If there are sequences of pre-processing tokens within the list of arguments

that would otherwise act as pre-processing directives, the behaviour is

undefined.

Rule 14.14 (avoids) QAC++

320 16.3.2 The # Operator (para 2)

If, in the replacement list, a parameter is immediately preceded by a # pre-

processing token, both are replaced by a single character literal pro-

processing token that contains the spelling of the pre-processing token

sequence for the corresponding argument. If the replacement that results is

not a valid character string literal, the behaviour is undefined.

New Rule (19) QAC++

320 16.3.3 The # # Operator (para 3)

For both object-like and function-like macro invocations, before the

replacement list is re-examined for more macro names to replace, each

instance of a # # pre-processing token in this replacement list (not from an

argument) is deleted and the preceding pre-processing token is concatenated

with the following pre-processing token. If the result is not a valid pre-

processing token, the behaviour is undefined.

New Rule (19) QAC++

322 16.4 Line Control (para 3, 5)

A pre-processing directive of the form

# line digit-sequence new-line

If the digit sequence specifies zero or a number greater than 32767, the

behaviour is undefined.

A pre-processor directive of the form

# line pp-tokens new-line

If the directive resulting after all replacements does not match one of the two

previous forms, the behaviour is undefined; otherwise the result is processed

as appropriate.

New Rule (20) No auto

323 16.8 Predefined Macro Names (para 3)

If any of the pre-defined macro names in this subclause, or the identifier

defined, is the subject of a #define or a #undef pre-processing directive,

the behaviour is undefined.

Rule 13.1 (avoids)

Rule 13.4 (avoids)

QAC++

partial

PC-Lint

partial

QAC++

Table 10-1: C++ Language Undefined Behaviour [BSI03]

Page 141: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

11-1

Appendix 11 – Undefined Behaviour (C++ STL)

The following table details undefined behaviour in the C++ STL and the applicable controls that

can be put in place to mitigate them. The behaviours have been extracted directly from [BSI03].

Page Item / Description Control Enforced

327 17 Library Introduction

17.1.15 Required Behaviour

If a function defined in the C++ program fails to meet the required

behaviour when it executes, behaviour is undefined.

Use a validated

compiler and STL

implementation

N/A

336 17.4.3.1 Reserved Names (para 1, 3)

It is undefined for a C++ program to add declarations or definitions to

namespace std or namespaces with namespace std unless otherwise

specified. A program may add specialisations for any standard library

template to namespace std. Such a specialisation (complete or partial) of a

standard library template results in undefined behaviour unless the

declaration depends on a user-defined name of external linkage and unless

the specialisation meets the standard library requirements for the original

template.

If a program declares or defines a name in a context where it is reserved,

other than as explicitly allowed, the behaviour is undefined.

Use a validated ISO

C++ compiler and

STL set

Rule 8.3.4 (direct) QAC++

partial

PC-Lint

partial

337 17.4.3.2 Headers (para 1)

If a file with a name equivalent to the derived file name for one of the C++

Standard Library headers is not provided as part of the implementation, and

a file with that name is placed in any of the standard places for a source file

to be included, the behaviour is undefined.

Use a ISO C++

compiler and

library set

338 17.4.3.7 Function Arguments (para 1)

If an argument to a function has an invalid value (such as a value outside the

domain of the function, or a pointer invalid for its intended use), the

behaviour is undefined.

New Rule (27)

New Rule (32)

No auto

No auto

339 17.4.3.8 Required Paragraph (para 1)

Violation of the preconditions specified in a function’s Required Behaviour

paragraph results in undefined behaviour unless the function’s Throw

paragraph specifies throwing an exception when the pre-condition is

violated.

New Rule (27)

New Rule (32)

No auto

No auto

344 18 Language Support Library

18.1 Types (para 5)

The macro offsetof accepts a restricted set of type arguments in this

International Standard. Type shall be POD structure and POD union. The

result of applying the offsetof macro to a field that is a static data member

or a function member is undefined.

New Rule (28) No auto

364 18.7 Other Runtime Support (para 3, 5)

The restrictions that ISO C places on the second parameter to the

va_start() macro in header <stdarg.h> are different in this

International Standard. If the parameter parmN is declared within a function,

array, or reference type, or with a type that is not compatible with the type

that results when passing an argument for which there is no parameter, the

behaviour is undefined.

The function signature longjmp(jmp_buf jbuf, int val) has more

restricted behaviour in this International Standard. If any automatic objects

would be destroyed by a thrown exception transferring control to another

point in the program, then a call to longjmp(jbuf, val) at the throw

point that transfers control to the same point has undefined behaviour.

Rule 17.1 (avoids) QAC++

Page 142: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

11-2

Page Item / Description Control Enforced

391 20 General Utilities Library

20.4.5 Class Template auto_ptr (para 3)

If more than one auto_ptr owns the same object at the same time the

behaviour is undefined.

The uses of auto_ptr include providing temporary exception-safety for

dynamically allocated memory, passing ownership of dynamically allocated

memory to a function, and returning dynamically allocated memory from a

function. auto_ptr does not meet the CopyConstructible and Assignable

requirements for Standard Library container elements and thus instantiating

a Standard Library container with an auto_ptr results in undefined

behaviour.

Rule 17.8 (direct)

Guideline 17.21

(direct)

No auto

No auto

411 21 String Library

21.3.4 basic_string Element Access (para 1)

const_reference operator[](size_type pos) const;reference operator[](size_type pos);

If pos < size(), returns data()[pos]. Otherwise, if pos ==

size(), the const version returns charT(). Otherwise the behaviour is

undefined.

New Rule (27)

New Rule (32)

No auto

No auto

501 23 Containers Library

23.2.2.4 list Operations (para 12)

void splice(iterator position, list<T,Allocator>& x,iterator first, iterator last);

The result is undefined if position is an iterator in the range [first, last].

New Rule (27) No auto

534 24 Iterator Library

24.1 Iterator Requirements (para 5, 7)

Results of most expressions are undefined for singular values; the only

exception is an assignment of a non-singular value to an iterator that holds

for a singular value.

The result of the application of functions in the library to invalid ranges is

undefined.

New Rule (29)

New Rule (27)

No auto

No auto

557 24.5.3 Class Template istreambuf_interator (para 2)

The result of operator*() on an end of stream is undefined.

New Rule (27) No auto

592 26 Numerics Library

26.1 Numeric Type Requirements (para 2, 3)

If any operation on T throws an exception the effects are undefined.

In addition, many member and related functions of valarray<T> can be

successfully instantiated and will exhibit well-defined behaviour if and only

if T satisfies additional requirements specified for each such member or

related function.

New Rule (30)

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

No auto

605 26.3.2.1 valarray Constructors (para 4)

valarray(const T*, size_t);

If the value of the second argument is greater than the number of values

pointed to by the first argument, the behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

Page 143: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

11-3

Page Item / Description Control Enforced

605-

60626.3.2.2 valarray Assignment (para 1, 4)

valarray<T>& operator=(const valarray<T>&);

The resulting behaviour is undefined if the length of the argument array is

not equal to the length of the *this array.

Valarray<T>& operator=(const slice_array<T>&);Valarray<T>& operator=(const gslice_array<T>&);Valarray<T>& operator=(const mask_array<T>&);Valarray<T>& operator=(const indirect_array<T>&);

If the value of the element in the left hand side of a valarray assignment

operator depends on the value of another element in that left hand side, the

resulting behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

606 26.3.2.3 valarray Element Access (para 6)

T operator[] (size_t) const;T& operator[] (size_t);

If the subscript operator is invoked with a size_t argument whose value is

not less than the length of the array, the behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

607 26.3.2.6 valarray Computer Assignment (para 3, 4)

valarray<T>& operator*= (const valarray<T>&);valarray<T>& operator/= (const valarray<T>&);valarray<T>& operator%= (const valarray<T>&);valarray<T>& operator+= (const valarray<T>&);valarray<T>& operator-= (const valarray<T>&);valarray<T>& operator^= (const valarray<T>&);valarray<T>& operator|= (const valarray<T>&);valarray<T>& operator<<= (const valarray<T>&);valarray<T>& operator>>= (const valarray<T>&);

If the array and the argument array do not have the same length, the

behaviour is undefined.

If the value of an element in the left hand side of a valarray computed

assignment depends on the value of another element in that left hand side,

the resulting behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

608 26.3.2.7 valarray Member Function (para 2, 3, 4)

T sum() const;T min() const;T max() const;

If the array has length 0, the behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

Page 144: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

11-4

Page Item / Description Control Enforced

609 26.3.3.1 valarray Binary Operators (para 3)

template<class T> valarray<T> operator* (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator/ (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator% (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator+ (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator- (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator& (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator| (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator<< (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator>> (constvalarray<T>&, const valarray<T>&);

If the argument arrays do not have the same length, the behaviour is

undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

610 26.3.3.2 valarray Logical Operators (para 3)

template<class T> valarray<T> operator== (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator!= (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator< (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator> (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator<= (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator>= (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator&& (constvalarray<T>&, const valarray<T>&);

template<class T> valarray<T> operator|| (constvalarray<T>&, const valarray<T>&);

If the argument arrays do not have the same length, the behaviour is

undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

615 26.3.6 The gslice Class (6)

If a degenerate slice is being used as the argument to the non-const version

of operator[](const gclice&), the resulting behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

619 26.3.9.2 indirect_array Assignment (para 2)

void operator=(const valarray<T>&) const;indirect_array& operator=(const indirect_array&);

If the indirect_array specifies an element in the valarray<T> object to

which it refers more than once, the behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

Page 145: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

11-5

Page Item / Description Control Enforced

620 26.3.9.3 indirect_array Computed Assignment (para 2)

void operator*= (const valarray<T>&) const;void operator/= (const valarray<T>&) const;void operator%= (const valarray<T>&) const;void operator+= (const valarray<T>&) const;void operator-= (const valarray<T>&) const;void operator^= (const valarray<T>&) const;void operator&= (const valarray<T>&) const;void operator|= (const valarray<T>&) const;void operator<<= (const valarray<T>&) const;void operator>>= (const valarray<T>&) const;

If the indirect_array specifies an element in the valarray<T> object to

which it refers more than once, the behaviour is undefined.

Rule 17.9 (avoids)

New Rule (27)

No auto

No auto

625 27 Input/Output Library

27.1.1 imbue Limitations

No function described in clause 27 except for ios_base::imbue causes an

instance of basic_ios::imbue or basic_streambuf::imbue to be

called. If any user function called from a function declared in clause 27 or as

an overriding virtual function of any class declared in clause 27 calls imbue,

the behaviour is undefined.

New Rule (31) No auto

639 27.4.3.2 fpos Requirements (para 2)

Stream operations that return a value of type traits::pos_type return

P(O(-1)) as an invalid value to signal an error. If this value is used as an

argument to any iostream, ostream, or streambuf member that accepts

a value of type traits::pos_type then the behaviour of that function is

undefined.

New Rule (27) No auto

641 27.4.4.1 basic_ios Constructors

basic_ios();

Constructs an object of class basic_ios leaving its member objects

uninitialised. The object must be initialised by calling its init member

function. If it is destroyed before it has been initialised the behaviour is

undefined.

New Rule (27) No auto

680 27.7.1.3 Overridden Virtual Function (para 14)

Alters the stream position within the controlled sequences, if possible, to

correspond to the stream position stored in sp (as described below).

If sp is an invalid stream position, or if the function positions neither

sequence, the positioning operation fails. If sp has not been obtained by a

previous successful call to one of the positioning functions (seekoff,

seekpos, tellg, tellb) the effect is undefined.

New Rule (27) No auto

685 27.8.1.1 Class Template basic_filebuf (para 4)

An instance of basic_filebuf behaves as described in 27.8.1.1 provided

traits::pos_type is fpos<traits::state_type>. Otherwise the

behaviour is undefined.

New Rule (27) No auto

689 27.8.1.4 Overridden Virtual Functions (para 14)

pos_type seekpos(pos_type sp, ios_base::openmode which =ios_base::in | ios_base::out);

If sp has not been obtained by a previous successful call to one of the

positioning functions (seekoff or seekpos) on the same file the effects are

undefined.

New Rule (27) No auto

Table 11-1: C++ STL Undefined Behaviour [BSI03]

Page 146: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12-1

Appendix 12 – Implementation-Defined Behaviour (C++ Lang)

The following table details implementation-defined behaviour in the C++ language and the

applicable controls that can be put in place to mitigate them. The behaviours have been extracted

directly from [BSI03].

Page Item / Description Control Enforced

9, 10 2 Lexical Conventions

2.1 Phases of Translation (para 1, 3, 8)

Physical source file characters are mapped, in an implementation-defined

manner, to the basic source character set (introducing new-line characters

for end-of-line indicators) if necessary.

Whether each non-empty sequence of white space characters other than

new-line is retained or replaced by one space character is implementation-

defined.

The definitions of the required templates are located. It is implementation-

defined whether the source of the translation units containing these

definitions is required to be available.

Guideline 13.1

(supports)

Rule 14.8 (direct)

Use a complete ISO

C++ compiler and

STL

implementation

No auto

QAC++

10 2.2 Character Sets (para 3)

The values of the members of the execution character sets are

implementation-defined, and any additional members are locale-specific.

Guideline 13.1

(supports)

No auto

13 2.8 Header Names (para 1)

The sequences in both forms of header-names are mapped in an

implementation-defined manner to headers or external source file names as

specified in 16.2.

Rule 14.9 (direct)

Rule 14.10 (direct)

Rule 14.12 (direct)

Guideline 13.1

(supports)

QAC++

QAC++

QAC++

No auto

17-

182.13.2 Character Literals (para 1, 2, 4, 5)

A multi-character literal has type int and implementation-defined value.

The value of a wide-character literal containing multiple c-chars is

implementation-defined.

The value of a character literal is implementation-defined if it falls outside

of the implementation-defined range defined for char (for ordinary literals)

or wchar_t (for wide literals).

A universal-character-name is translated to the encoding, in the execution

character set, of the character named. If there is no such encoding, the

universal-character-name is translated to an implementation defined

encoding.

Guideline 13.1

(supports)

Rule 13.6 (direct)

No auto

QAC++

partial

19 2.13.3 Floating Literals (para 1)

If the scaled value is in the range of representable values for its type, the

result is the scaled value if representable, else the larger or smaller

representable value nearest the scaled value, chosen in an implementation-

defined manner.

Rule 10.14 (direct)

Rule 10.15 (avoids)

Guideline 13.1

(supports)

Rule 6.2 (direct)

QAC++

QAC++

No auto

QAC++

19 2.13.4 String Literals (para 2)

Whether all string literals are distinct (that is, are stored in non-overlapping

objects) is implementation-defined.

Rule 13.6 (direct)

Guideline 13.1

(supports)

QAC++

partial

PC-Lint

partial

No auto

Page 147: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12-2

Page Item / Description Control Enforced

44 3 Basic Concepts

3.6.1 Main Function (para 1, 2, 3)

A program shall contain a global function called main, which is the

designated start of the program. It is implementation-defined whether a

program on a free-standing environment is required to define a main

function.

An implementation shall not predefine the main function. This function

shall not be overloaded. It shall have a return type of type int, but

otherwise its type is implementation defined. It is recommended that any

further (optional) parameters be added after argv.

The function main shall not be used within a program. The linkage of main

is implementation defined.

Guideline 13.1

(supports)

No auto

QAC++

PC-Lint

45 3.6.2 Initialisation of Non-Local Objects (para 3)

It is implementation-defined whether or not the dynamic initialisation of an

object of namespace scope is done before the first statement of main.

Guideline 13.1

(supports)

Rule 8.2.2 (direct)

No auto

QAC++

partial

53 3.9 Types (para 4, 5)

For POD types, the value representation is a set of bits in the object

representation that determines a value, which is one discrete element of an

implementation-defined set of values.

The alignment of a complete object type is an implementation-defined

integer value representing a number of bytes; an object is allocated an

address that meets the alignment requirements of its object type.

Guideline 13.1

(supports)

Rule 13.6 (direct)

No auto

QAC++

partial

PC-Lint

partial

54-

553.9.1 Fundamental Types (para 1, 2, 5, 8)

Objects declared as characters (char) shall be large enough to store any

member of the implementation’s basic character set. It is implementation

defined whether a char can hold negative values. In any particular

implementation, a plain char object can take on either the same values as a

signed char or an unsigned char; which is implementation defined.

Plain ints have the natural size suggested by the architecture of the execution

environment; other signed integer types are provided to meet special needs.

Type wchar_t is a distinct type whose values can represent distinct codes

for all members of the largest extended character set specified among the

support locales.

The value representation of floating point types is implementation defined.

Specialisations of the standard template numeric limits shall specify the

maximum and minimum values of each arithmetic type for an

implementation.

Guideline 2.2

(direct)

Rule 8.4.5 (direct)

Guideline 8.4.13

(direct)

Guideline 13.1

(supports)

Guideline 13.6

(direct)

No auto

PC-Lint

partial

PC-Lint

partial

QAC++

Partial

No auto

QAC++

partial

PC-Lint

partial

56 3.9.2 Compound Types (para 3)

The value representation of pointer types is implementation-defined.

Guideline 13.1

(supports)

Rule 13.6 (direct)

No auto

QAC++

partial

PC-Lint

partial

Page 148: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12-3

Page Item / Description Control Enforced

62 4 Standard Conversions

4.7 Integral Conversions (para 3)

If the destination type is signed, the value is unchanged if it can be

represented in the destination type (and bit-field width); otherwise, the value

is implementation defined.

Guideline 13.1

(supports)

Guideline 8.4.13

(direct)

Guideline 10.7

(avoids)

Rule 10.13 (direct)

No auto

QAC++

partial

PC-Lint

partial

QAC++

QAC++

62 4.8 Floating Point Conversions (para 1)

If the source value is between two adjacent destination values, the result of

the conversion is an implementation-defined choice of either of these values.

Guideline 10.7

(direct)

Rule 10.14 (direct)

Rule 10.15 (direct)

Guideline 13.1

(supports)

QAC++

QAC++

QAC++

No auto

62 4.9 Floating-Integral Conversions (para 2)

An rvalue of an integer type or of an enumeration type can be converted to

an rvalue of a floating point type. The result is exact if possible. Otherwise it

is an implementation-defined choice of either the next lower or higher

representable value.

Rule 10.14 (direct)

Guideline 13.1

(supports)

QAC++

No auto

73 5 Expressions

5.2.8 Type Identification (para 1)

The result of a typeid expression is an lvalue of static type const

std::type_info and dynamic type const std::type_info or const

name where name is an implementation-defined class derived from

std::type_info which preserves the behaviour described in 18.5.1.

Guideline 13.1

(supports)

QAC++

76 5.2.10 Reinterpret Cast (para 3, 4, 5)

The mapping performed by reinterpret_cast is implementation-

defined.

A pointer can be explicitly converted to any integral type large enough to

hold it. The mapping function is implementation defined.

A value of an integral type or enumeration type can be explicitly converted

to a pointer. A pointer converted to an integer of sufficient size and back to

the same pointer type will have its original value; mappings between

pointers and integers are otherwise implementation-defined.

Guideline 7.2

(avoids)

Rule 7.5 (avoids)

Rule 7.7 (avoids)

Guideline 13.1

(supports)

QAC++

QAC++

QAC++

No auto

79 5.3.3 Sizeof (para 1)

sizeof(char), sizeof(signed char) and sizeof(unsigned char)

are 1; the result of sizeof applied to any other fundamental type is

implementation defined. In particular sizeof(bool) and

sizeof(wchar_t) are implementation defined.

Guideline 13.1

(supports)

Rule 13.6 (direct)

No auto

QAC++

partial

81 5.3.4 New (para 8)

An implementation shall provide default definitions for the global allocation

functions (3.7.3, 18.4.1.1, 18.4.1.2).

Guideline 13.1

(supports)

No auto

86 5.6 Multiplicative Operators (para 4)

The binary / operator yields the quotient, and the binary % operator yields

the remainder from the division of the first expression by the second. If both

operands are non-negative then the remainder is non-negative; if not the sign

of the remainder is implementation-defined.

Guideline 10.18

(direct)

Guideline 13.1

(supports)

QAC++

partial

PC-Lint

partial

87 5.7 Additive Operators (para 6)

When two pointers to elements of the same array object are subtracted, the

result is the difference of the subscripts of the two array elements. The type

of the result is an implementation-defined signed integral type; this type

shall be the same type that is defined as ptrdiff_t in the <cstddef>

header.

Guideline 13.1

(supports)

No auto

Page 149: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12-4

Page Item / Description Control Enforced

88 5.8 Shift Operators (para 3)

The value E1 >> E2 is E1 (interpreted as a bit pattern) left shifted E2 bit

positions. If E1 has an unsigned type or if E1 has a signed type and a

nonnegative value, the value result in the integral part of the quotient of E1

divided by the quantity 2 raised to the power E2. If E1 has a signed type and

a negative value, the resulting value is implementation-defined.

Rule 10.11 (direct)

Rule 10.12 (direct)

Guideline 13.1

(supports)

QAC++

QAC++

112 7 Declarations

7.1.5.2 Simple Type Specifiers (para 1)

It is implementation-defined whether bit-fields and objects of char type are

represented as signed or unsigned quantities.

Rule 2.2 (direct)

Rule 8.4.5 (direct)

Guideline 13.1

(supports)

Rule 13.6 (direct)

No auto

QAC++

partial

PC-Lint

partial

QAC++

partial

PC-Lint

partial

114 7.2 Enumeration Declarations (para 5)

It is implementation-defined which integral type is used in the underlying

type for an enumeration except that the underlying type shall not be larger

than int unless the value of an enumerator cannot fit in an int or

unsigned int.

Guideline 13.1

(supports)

Rule 13.6 (direct)

No auto

QAC++

partial

PC-Lint

partial

127 7.4 The asm Declaration (para 1)

The meaning of the asm declaration is implementation-defined.

Rule 13.5 (direct)

Guideline 13.1

(supports)

QAC++

No auto

128,

1307.5 Linkage Specification (para 1, 2, 3, 9)

Some of the properties associated with an entity with language linkage are

specific to each implementation and are not described here.

The string literal indicates the required language linkage. The meaning of

the string literal is implementation defined. A linkage-specification with a

string that is unknown to the implementation is ill-formed. When the string-

literal in a linkage-specification names a programming language, the

spelling of the programming language’s name is implementation defined.

The semantics of a language linkage other than C++ or C are

implementation defined.

Every implementation shall provide for linkage to functions written in the C

programming language, “C”, and linkage to C++ functions, “C++”.

Linkage from C++ to objects defined in other languages and to objects

defined in C++ from other languages is implementation-defined and

language-dependant.

Guideline 13.1

(supports)

New Guideline

(18)

Rule 14.6 (direct)

No auto

No auto

No auto

152 8 Declarators

8.5.3 References (para 5)

A reference to type “cv1 T1” is initialised by an expression if the initialiser

expression is an lvalue and “cv1 T1” is reference-compatible with “cv2 T2”,

or has a class type and can be implicitly converted to an lvalue of type “cv3

T3”, where “cv1 T1” is reference compatible with “cv3 T3”. Otherwise the

reference shall be to a non-volatile const type. If the initialiser expression is

an rvalue, with T2 a class type, and “cv1 T1” is reference-compatible with

“cv2 T2”, the reference is bound in one of the several ways (the choice is

implementation defined).

Guideline 13.1

(supports)

Guideline 10.7

(direct)

No auto

QAC++

166 9 Classes

9.6 Bit-Fields (para 1, 3)

Allocation of bit-fields within a class object is implementation defined.

Alignment of bit-fields is implementation-defined.

It is implementation defined whether a plain (neither explicitly signed or

unsigned) char, short, int or long bit-field is signed or unsigned.

Guideline 13.1

(supports)

Rule 13.6 (direct)

Rule 10.13 (direct)

Rule 2.2 (direct)

No auto

QAC++

partial

PC-Lint

partial

QAC++

No auto

Page 150: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12-5

Page Item / Description Control Enforced

246 14 Templates (para 4)

A template name has linkage. If the linkage of one of these is something

other than C or C++, the behaviour is implementation-defined.

Guideline 13.1

(supports)

New Guideline

(18)

No auto

No auto

283 14.7.1 Implicit Instantiation (para 14)

There is an implementation-defined quantity that specifies the limit of the

total depth of recursive instantiations, which could involve more than one

template.

Guideline 13.1

(supports)

Rule 13.3 (direct)

No auto

No auto

309 15 Exception Handling

15.3 Handling an Exception (para 9)

If no matching handler is found in a program, the function terminate() is

called; whether or not the stack is unwound before this call to

terminate() is implementation-defined.

Guideline 13.1

(supports)

No auto

313 15.5.2 The unexpected() Function (para 2)

If the exception-specification does not include the class

std::bad_exception then the function terminate() is called,

otherwise the thrown exception is replaced by an implementation-defined

object of the type std::bad_exception and the search for another

handler will continue at the call of the function whose exception-

specification was violated.

Guideline 13.1

(supports)

No auto

316,

31716 Preprocessing Directives

16.1 Conditional Inclusion (para 4)

This includes interpreting character literals, which may involve converting

escape sequences into execution character set members. Whether the

numeric character value for these character literals matches the value

obtained when an identical character literal occurs in the expression (other

than within a #if or #elif directive) is implementation-defined.

Also, whether a single-character character literal may have a negative value

is implementation-defined.

Guideline 13.1

(supports)

Guideline 8.4.13

(direct)

Rule 6.4 (direct)

No auto

QAC++

QAC++

317,

31816.2 Source File Inclusion (para 2, 3, 4, 5, 6)

A preprocessor directive of the form# include <h-char-sequence> new-line

searches a sequence of implementation-defined places for a header identified

uniquely by the specified sequence between the < and > delimiters, and

causes the replacement of that directive by the entire contents of the header.

How the places are specified or the header identified is implementation-

defined.

A preprocessor directive of the form# include “q-char-sequence” new-line

causes the replacement of that directive by the entire contents of the source

file identified by the specified sequence between the “ delimiters. The names

source file is searched in an implementation-defined manner.

A preprocessor directive of the form# include pp-tokens new-line

is permitted. The method by which the sequence of preprocessing tokens

between a < and a > preprocessing token pair or a pair of “ characters is

combined into a single header name preprocessing token is implementation

defined.

The mapping between the delimited sequence and the external source file

name is implementation defined.

A #include preprocessing directive may appear in a source file that has been

read because of a #include directive in another a file, up to an

implementation-defined nesting limit.

Guideline 13.1

(supports)

Rule 14.9 (direct)

Rule 14.10 (direct)

Rule 14.12 (direct)

No auto

QAC++

QAC++

QAC++

Page 151: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

12-6

Page Item / Description Control Enforced

323 16.6 Pragma Directive (para 1)

A preprocessing directive of the form

# pragma pp-tokensopt new-line

causes the implementation to behave in an implementation-defined manner.

Guideline 13.1

(supports)

Rule 13.4 (direct)

No auto

QAC++

323 16.8 Predefined Macro Names (para 1)

The following macro names shall be defined by the implementation:

__LINE__

__FILE__

__DATE__: If the date of translation is not available, an implementation-

defined valid date is supplied.

__TIME__: If the time of translation is not available, an implementation-

defined valid time is supplied.

__STDC__: Whether __STDC__ is predefined and if so, what its value is, is

implementation-defined.

__cplusplus

Guideline 13.1

(supports)

Rule 13.4 (direct)

No auto

QAC++

Table 12-1: C++ Language Implementation-Defined Behaviour [BSI03]

Page 152: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

13-1

Appendix 13 – Implementation-Defined Behaviour (C++ STL)

The following table details implementation-defined behaviour in the C++ STL and the applicable

controls that can be put in place to mitigate them. The behaviours have been extracted directly from

[BSI03].

Page Item / Description Control Enforced

330 17 Library Introduction

17.3.2.1 Type Descriptions (para 2)

Certain types described in this clause are used to describe implementation-

define types, and member function.

Noted control not

required

N/A

330 17.3.2.1.1 Enumeration Types (para 1)

Each enumerated type may be implemented as an enumeration or as a

synonym for an enumeration.

Rule 13.6 (avoids) No auto

335 17.4.1.3 Freestanding Implementations (para 2)

A freestanding implementation has an implementation-defined set of

headers. This set shall include at the least the following headers: <cstddef>,

<limits>, <cstdlib>, <new>, <type_info>, <exception>, <cstdarg>.

Rule 17.1 (direct) QAC++

335 17.4.2.2 Linkage (para 2)

It is implementation-defined whether a name from the Standard C Library

declared with external linkage has extern “C” or extern “C++” linkage.

Rule 17.1 (avoids)

Rule 14.6 (direct)

QAC++

No auto

339 17.4.4.3 Global or Non-member Functions (para 2)

A call to a global or non-member function signature in clauses 18 through

27 behaves the same as if the implementation declares no additional global

or non-member function signatures. An implementation may also define

additional global and non-member functions that would otherwise not be

called by a valid C++ program.

Efficiency

Guideline 13.1

(supports)

No auto

340 17.4.4.5 Reentrancy (para 1)

Which of the functions in the C++ Standard Library that are not reentrant

subroutines is implementation-defined.

Guideline 13.1

(supports)

No auto

341 17.4.4.8 Restrictions on Exception Handling (para 1, 3)

An implementation may strengthen the exception-specification for a non-

virtual function by removing listed exceptions.

No destructor operation defined in the C++ Standard Library will throw an

exception. Any other functions defined in the C++ Standard Library that do

not have an exception-specification may throw implementation-defined

exceptions unless otherwise specified. An implementation may strengthen

this implicit exception-specification by adding an explicit one. This implies

that the implementation may list implementation-defined types in such an

exception-specification.

Guideline 13.1

(supports)

No auto

343 18 Language Support Library

18.1 Types (para 4)

The macro NULL is an implementation-defined C++ null pointer constant in

this International Standard. Possible definitions include 0, 0L, but not

(void *) 0.

Rule 14.16 (direct) QAC++

353 18.3 Start and Termination (para 8)

Finally, control is returned to the host environment. If status is zero or

EXIT_SUCCESS, an implementation-defined form of the status successful

termination is returned. If status is EXIT_FAILURE, an implementation-

defined form of the status unsuccessful termination is returned. Otherwise

the status returned is implementation-defined.

Guideline 13.1

(supports)

No auto

357 18.4.2.1 Class bad_alloc (para 3, 5)

The result of calling what() on the newly constructed object is

implementation-defined.

virtual const char* what() const throw();

Returns an implementation-defined NTBS

Guideline 13.1

(supports)

No auto

Page 153: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

13-2

Page Item / Description Control Enforced

359 18.5.1 Class type_info (para 7)

const char* name() const;

Returns an implementation-defined NTBS

Guideline 13.1

(supports)

No auto

359 18.5.2 Class bad_cast (para 3, 5)

The result of calling what() on the newly constructed object is

implementation-defined.

virtual const char* what() const throw();

Returns an implementation-defined NTBS

Guideline 13.1

(supports)

No auto

360 18.5.2 Class bad_typeid (para 3, 5)

The result of calling what() on the newly constructed object is

implementation-defined.

virtual const char* what() const throw();

Returns an implementation-defined NTBS

Guideline 13.1

(supports)

No auto

361 18.6.1 Class exception (5, 8)

The effects of calling what() after assignment are implementation-defined.

virtual const char* what() const throw();

Returns an implementation-defined NTBS

Guideline 13.1

(supports)

No auto

362 18.5.2 Class bad_exception (para 3, 5)

The result of calling what() on the newly constructed object is

implementation-defined.

virtual const char* what() const throw();

Returns an implementation-defined NTBS

Guideline 13.1

(supports)

No auto

364 18.7 Other Run-Time Support (para 5)

All signal handlers shall have C linkage. A POF that could be used as a

signal handler in a conforming C program does not produce undefined

behaviour when used as a signal handler in a C++ program. The behaviour

of any other function used as a signal handler in a C++ program is

implementation-defined.

Guideline 13.1

(supports)

No auto

375 20 General Utilities Library

20.1.5 Allocator Requirements

Implementors are encouraged to supply libraries that can accept allocators

than encapsulate more general memory models and that support non-equal

instances. In such implementations, any requirements imposed on allocators

by containers beyond those requirements that appear in Table 32, and the

semantics of containers and algorithms when allocator instances compare

non-equal, are implementation-defined.

Guideline 13.1

(supports)

No auto

398 21 Strings Library

21.1.3.1 struct char_traits<char> (para 3, 4, 5)

The type streampos is an implementation-defined type that satisfies the

requirements for POS_T in 21.1.2.

The type streamoff is an implementation-defined type that satisfies the

requirements for OFF_T in 21.1.2.

The type mbstate_t is defined in <cwchar> and can represent any of the

conversion states possible to occur in an implementation-defined set of

supported multibyte character encoding rules.

Guideline 13.1

(supports)

No auto

Page 154: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

13-3

Page Item / Description Control Enforced

399 21.1.3.2 struct char_traits<wchar_t> (para 2, 4)

The type wstreampos is an implementation-defined type that satisfies the

requirements for POS_T in 21.1.2.

The type mbstate_t is defined in <cwchar> and can represent any of the

conversion states possible to occur in an implementation-defined set of

supported multibyte character encoding rules.

Guideline 13.1

(supports)

No auto

436 22 Localisation Library

22.1.1.2 locale Constructors and Destructor (para 8)

explicit locale(const char* std_name);

The set of valid string argument values is “C”, “ “, and any implementation-

defined values.

Guideline 13.1

(supports)

No auto

436 22.1.1.3 locale Members (para 5)

basic_string<char> name() const;

Returns the name of *this, if it has one; otherwise, the string “*”. If *this

has a name, then locale(name().c_str()) is equivalent to *this.

Details of the contents of the result string are otherwise implementation

defined.

Guideline 13.1

(supports)

No auto

437 22.1.1.5 locale Static Members (para 2)

static locale global(const locale& loc);

Causes future calls to the constructor locale() to return a copy of the

argument. If the argument has a name, does std::setlocale(LC_ALL,

loc.name().c_str()); otherwise, the effect on the C locale, if any, is

implementation-defined.

Guideline 13.1

(supports)

No auto

444 22.2.1.3 ctype Specialisations (para 1)

A specialisation ctype<char> is provided so that a member function of type

char can be implemented inline. The implementation-define value of

member table_size is at least 256.

Guideline 13.1

(supports)

No auto

444 22.2.1.3.2 ctype<char> Members (para 1)

In the following member descriptions, for unsigned char values v where

(v >= table_size), table()[v] is assumed to have an

implementation-define value (possibly different for each such value v)

without performing the array lookup.

Guideline 13.1

(supports)

No auto

447 22.2.1.5 Class Template codecvt (para 3)

The instantiations required in the Table 51, namely

codecvt<wchar_t,char,mbstate_t> and

codecvt<char,char,mbstate_t>, convert the implementation-defined

native character set.

Guideline 13.1

(supports)

No auto

467 22.2.5.3.2 time_put Virtual Functions (para 1)

iter_type do_put(iter_type s, ios_base&, char_type fill,const tm* t, char format, char modifier) const;

Formats the contents of the parameter t into characters placed on the output

sequence s. Formatting is controlled by the parameters format and modifier,

interpreted identically as the format specifiers in the string argument to the

standard library strftime(). Interpretation of the modifier argument is

implementation defined, but should follow POSIX conventions. Except that

the sequence of characters produced for those specifiers that are described as

depending on the C locale are instead implementation-defined.

Guideline 13.1

(supports)

No auto

Page 155: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

13-4

Page Item / Description Control Enforced

494 23 Container Library

23.2.1 Class Template deque (para 2)

23.2.2 Class Template list (para 2)

23.2.4 Class Template vector (para 2)

The typedefs iterator, const_iterator, size_type,

difference_type are implementation-defined.

Guideline 13.1

(supports)

Guideline 17.16

No auto

No auto

599 26 Numerics Library

26.2.8 complex Transcendentals (para 9)

template<class T> complex<T> pow<const complex<T>& x, inty);

template<class T> complex<T> pow<const complex<T>& x,const complex<T>& y);

template<class T> complex<T> pow<const complex<T>& x,const T& y);

template<class T> complex<T> pow<const T& x, constcomplex<T>& y);

Returns the complex power of base x raised to the y-th power, defined as

exp(y*log(x)). The value returned for pow(0,0) is implementation-

defined.

Guideline 13.1

(supports)

No auto

625 27 Input/Output Library

27.1.2 Positioning Type Limitations

The classes of clause 27 with template arguments charT and traits behave

as described if traits::pos_type and traits::off_type are

streampos and streamoff respectively. Except as noted explicitly below,

their behaviour when traits::pos_type and traits::off_type are

other types is implementation defined.

Guideline 13.1

(supports)

No auto

631 27.4.1 Types (para 1)

The type streamoff is an implementation-defined type that satisfies the

requirements of 27.4.3.2.

Guideline 13.1

(supports)

No auto

637 27.4.2.5 ios_base Storage Functions (para 2)

long& iword(int idx);

Each newly allocated element of the array is initialised to zero. The

reference returned is invalid after any other operations on the object. An

implementation is free to implement both the integer array pointed at by

iarray and the pointer array pointed at by parray as sparse data

structures, possibly with a one element cache for each.

Guideline 13.1

(supports)

No auto

643 27.4.4.3 basic_ios iostate Flags Function (para 5)

void clear(iostate state = goodbit);

If (rdstate() & exceptions()) ==0, returns. Otherwise, the function

throws an object fail of class_ios::failure, constructed with

implementation defined argument values.

Guideline 13.1

(supports)

No auto

659 27.6.1.1.2 Class basic_istream::sentry (para 5)

If, after any preparation is completed, is.good() is true, ok_ != false

otherwise ok_ == false. During preparation, the constructor may call

setstate(failbit). The sentry constructor and destructor can also

perform additional implementation-dependant operations.

Guideline 13.1

(supports)

No auto

669 27.6.2.3 Class basic_ostream::sentry (para 3)

If, after any preparation is completed, os.good() is true, ok_ != false

otherwise ok_ == false. During preparation, the constructor may call

setstate(failbit). The sentry constructor and destructor can also

perform additional implementation-dependant operations.

Guideline 13.1

(supports)

No auto

Page 156: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

13-5

Page Item / Description Control Enforced

674 27.6.3 Standard Manipulators (para 2)

The type designated smanip in each of the following function descriptions

is implementation-specified and may be different for each function.

smanip resetiosflags(ios_base::fmtflags mask);smanip setiosflags(ios_base::fmtflags mask);smanip setbase(int base);smanip setfill(char_type c);smanip setprecision(int n);smanip setw(int n);

Guideline 13.1

(supports)

No auto

680 27.7.1.3 Overridden Virtual Functions(para 16)

basic_streambuf<charT,traits>* setbuf(charT* s,streamsize n);

The effects are implementation-defined, except that setbuf(0,0) has no

effect.

Guideline 13.1

(supports)

No auto

688-

68927.8.1.4 Overridden Virtual Functions (para 10, 16)

basic_streambuf<charT,traits>* setbuf(charT* s,streamsize n);

If setbuf(0,0) is called on a stream before any I/O has occurred on that

stream, the stream becomes unbuffered. Otherwise the results are

implementation defined.

int sunc();

If a put area exists, calls filebuf::overflow to write the characters to the

file. If a get area exists, the effect is implementation defined.

Guideline 13.1

(supports)

No auto

713 Annex B Implementation Quantities

The limits may constrain quantities that include those described below or

others. The bracketed number following each quantity is recommended as

the minimum for that quantity. However, these quantities are only guidelines

and do not determine compliance.

Guideline 13.1

(supports)

No auto

727 C.2.2.3 Macro NULL (para 1)

The macro NULL, defined in any of <clocale>, <cstddef>, <cstdio>,

<cstdlib>, <cstring>, <ctime>, or <cwchar>, in an implementation-defined

C++ null pointer constant in this International Standard.

Rule 14.16 (direct) QAC++

730 D.6 Old iostream Members (para 5, 6, 7, 8)

The type streampos is an implementation-defined type that satisfies the

requirements of POS_T.

The type streamoff is an implementation-defined type that satisfies the

requirements of OFF_T.

An implementation may provide the following additional member function,

which has the effect of calling sbumpc().

An implementation may provide the following member functions that

overload signatures specified in clause 27.

Guideline 13.1

(supports)

No auto

Table 13-1: C++ STL Implementation-Defined Behaviour [BSI03]

Page 157: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

14-1

Appendix 14 – Indeterminate Behaviour (C++ Language)

The following table details indeterminate behaviour in the C++ language and the applicable controls

that can be put in place to mitigate them. The behaviours have been extracted directly from [BSI03].

Page Item / Description Control Enforced

25 3 Basic Concepts

3.3.1 Point of Declaration (para 1)

int x = 12;{ int x = x; }

Here the second x is initialised with its own (indeterminate) value.

Rule 8.2.1 (direct)

New Rule 8

QAC++

QAC++

partial

PC-Lint

partial

82 5 Expressions

5.3.4 New (para 15)

A new-expression that creates an object of type T initialises the object as

follows: If the initialiser is omitted and if T is a non-POD class type (or

array thereof), the object is default initialised. Otherwise, the object created

has indeterminate value.

Rule 8.4.3 (direct) QAC++

84 5.3.5 Delete (para 4)

The value of a pointer that refers to de-allocated storage is indeterminate.

Rule 12.8 (avoids) QAC++

partial

PC-Lint

partial

147 8 Declarators

8.5 Initialisers (para 9)

If no initialiser is specified for an object, and the object is of non-POD class

type (or array thereof), the object shall be default initialised; if the object is

of const-qualified type the underlying class type shall have a user-declared

default constructor. Otherwise, if no initialiser is specified for a non-static

object, the object and its sub-objects, if any, have an indeterminate value.

Rule 8.4.3 (direct) QAC++

206 12 Special Member Functions

12.6.2 Initialising Bases and Members (para 4)

After the call to a constructor for class X has completed, if a member of X is

neither specified in the constructor’s mem-initialisers, nor default-initialised,

nor value-initialised, nor given a value during execution of the body of the

constructor, the member has indeterminate value.

Rule 8.4.3 (direct) QAC++

Table 14-1: C++ Language Indeterminate Behaviour [BSI03].

Page 158: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

15-1

Appendix 15 – Rule and Guideline Enforcement Required

Guideline 2.2 – Specify in your compiler configuration that plain ‘char’ is implemented as

‘unsigned char’. Enforcement: Static, Environment

Rule 3.1.9 – Behaviour should be implemented by only one member function in a class.

Enforcement: Static, Design

Rule 3.2.5 – Ensure destructors release all resources owned by the object. Enforcement: Static

& Dynamic, Design & Coding

Rule 3.3.6 – If a virtual function in a base class is not overridden in any derived class then

make it non virtual. Enforcement: Static, Design

Rule 3.3.7 – Only define virtual functions in a base class if the behaviour will always be valid

default behaviour for derived classes. Enforcement: Static, Design

Rule 3.3.8 – Declare a function pure virtual in the base class if each derived class has to

provide specific behaviour. Enforcement: Static, Design

Rule 3.3.9 – If a virtual function is overridden in each derived class with the same

implementation then make it a non-virtual function in the base class. Enforcement: Static,

Design

Rule 3.3.10 – Ensure that the return type of the virtual function being overridden is

compatible. Enforcement: Static, Design

Rule 3.4.6 – Write derived classes to have at most one base class which is not a pure abstract

class. Enforcement: Static, Design

Guideline 3.4.7 – All members of a public base class must be valid for a derived class.

Enforcement: Static, Design

Rule 3.5.2 – Always write operations, that are normally equivalent, to be equivalent when

overloaded. Enforcement: Static, Design

Rule 6.1 – Use suffixes L, U, and UL for all constants of type ‘long’, ‘unsigned int’ and

‘unsigned long’. Enforcement: Static, Coding

Guideline 6.6 – Global and static data should be const. Enforcement: Static, Design & Coding

Guideline 8.3.2 – Restrict the use of the ‘extern’ keyword. Do not write ‘extern’ where it is

implicit. Enforcement: Static, Coding

Rule 8.3.5 – Avoid ambiguous grammar between function style casts and declarations.

Enforcement: Static, Coding

Rule 8.4.4 – Postpone variable definitions as long as possible. Enforcement: Static, Design &

Coding

Guideline 8.4.6 – Use class types or typedefs to indicate scaler quantities. Enforcement: Static,

Design & Coding

Page 159: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

15-2

Rule 8.4.9 – Do not use unbounded (C-style) aggregate types. Enforcement: Static, Design &

Coding

Rule 8.4.11 – Use ‘const’ whenever possible. Enforcement: Static, Design & Coding

Guideline 8.4.12 – Directly append the ‘*’ and ‘&’ to type names in declarations and

definitions. Enforcement: Static, Coding

Guideline 9.4 – Only use the C++ exception handling mechanism to handle error conditions.

Enforcement: Static, Design

Guideline 9.5 – Each application must have some scheme for ensuring that all orphaned

resources are properly released when an exception is thrown. Enforcement: Dynamic, Design

Guideline 9.6 – Each application that acquires resources that are not automatically freed at

program termination must use some mechanism to ensure that acquired resources are freed if

the program unexpectedly terminates. Enforcement: Dynamic, Design

Rule 10.6 – When comparing variables and constants for equality always place the constant

on the left hand side. Enforcement: Static, Coding

Rule 10.8 – Ensure expressions used in assertions are free from side-effects. Enforcement:

Static & Dynamic, Design & Coding

Rule 10.18 – Guard the modulas operation to ensure that both arguments are non-negative.

Enforcement: Static, Coding

Rule 11.2 – Enclose all non-member functions that are not part of the external interface in the

unnamed namespace in the source file. Enforcement: Static, Design & Coding

Rule 11.5 – Declare read-only parameters of class type as const references. Pass by value

read-only parameters that are of fundamental type. Enforcement: Static, Coding

Rule 12.1 – Do not use default arguments with overloaded functions. Enforcement: Static,

Coding

Rule 12.5 – Do not return a de-referenced pointer initialised by dynamic allocation with a

function. Enforcement: Static & Dynamic, Design & Coding

Rule 12.8 – On use of delete always set the pointer to zero after the delete. Enforcement: Static,

Coding

Guideline 13.1 – Avoid implementation behaviour. Enforcement: Static, Design & Coding

Rule 13.3 – Do not exceed the translation limits imposed by the ISO C++ standard.

Enforcement: Static, Design

Rule 13.6 – Do not make any assumptions about the internal representation of a value or

object. Enforcement: Static, Design & Coding

Rule 14.6 – Use the __cplusplus identifier to distinguish between C and C++ compilation.

Enforcement: Static, Coding

Page 160: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

15-3

Rule 14.13 – Write header files such that all files necessary for their compilation are included.

Enforcement: Static, Design & Coding

Rule 16.2 – Do not define a class template with potentially conflicting methods. Enforcement:

Static, Coding

Rule 16.3 – Only instantiate templates with template arguments which fulfil the interface

requirements of the ‘template’. Enforcement: Static & Dynamic, Design

Rule 16.4 – Only use templates when behaviour of the class or function template is completely

independent of the type of the object to which it is applied. Enforcement: Static, Design

Rule 17.2 – Use Standard Template Library containers and algorithms in preference to

custom designs. Enforcement: Static, Design

Guideline 17.3 – Make copying efficient for objects in containers. Enforcement: Static, Design

Guideline 17.4 – Where copying is expensive use containers of pointers or smart pointers.

Enforcement: Static, Design

Rule 17.5 – Do not attempt to insert derived class objects in a container that holds base class

objects. Enforcement: Static, Design & Coding

Rule 17.6 – Use empty() instead of checking size() against zero. Enforcement: Static, Design

Guideline 17.7 – Do not use STL containers as public base classes. Enforcement: Static, Design

Rule 17.8 – Never create containers of auto_ptrs. Enforcement: Static, Design & Coding

Rule 17.9 – Use vector and string in place of dynamically allocated arrays. Enforcement: Static,

Design

Rule 17.10 – Where possible pre-allocate in containers to save unnecessary reallocations.

Enforcement: Static, Design

Rule 17.11 – When passing vector types to C style functions use '&v[ 0 ]'. Enforcement: Static,

Coding

Rule 17.12 – Only use STL string's member c_str to get a const char* to use with legacy

functions. Enforcement: Static, Coding

Rule 17.13 – Do not use vector<bool>. Enforcement: Static, Coding

Rule 17.14 – Return false for equivalent values in relational predicates. Enforcement: Static,

Design & Coding

Rule 17.15 – Never modify the key part of a set or multiset element. Enforcement: Static,

Design & Coding

Guideline 17.16 – Minimise mixing of iterator types. Enforcement: Static, Design & Coding

Guideline 17.17 – The result of a predicate should depend only on its parameters.

Enforcement: Static, Design & Coding

Page 161: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

15-4

Guideline 17.18 – Use STL algorithms rather than hand-written loops. Enforcement: Static,

Design

Rule 17.19 – Use container member functions rather than algorithms with the same name.

Enforcement: Static, Design

Rule 17.20 – Directly include necessary STL headers. Enforcement: Static, Design & Coding

Guideline 17.21 – Minimise use of the Standard Template Library 'auto_ptr'. Enforcement:

Static, Design & Coding

New Rule 1 – Always return stream references from operator << and operator >>.

Enforcement: Static, Design & Coding

New Rule 3 – Do not assume constructor arguments will or will not be evaluated prior to the

allocation of the object occurring. Enforcement: Static, Design

New Rule 7 – Do not perform equality comparisons on pointers to virtual functions.

Enforcement: Static & Dynamic, Design & Coding

New Rule 13 – Do not rely on the lifetime of temporary exception objects. Enforcement:

Dynamic, Design

New Guideline 16 – Be prepared for out of memory conditions. Enforcement: Dynamic, Design

New Guideline 18 – Avoid linking to languages other than C++ or C. Enforcement: Static,

Design

New Rule 20 – Ensure that the digit sequence for the # line pre-processing directive is > 0

and < 32768. Enforcement: Static, Coding

New Guideline 21 - Choose carefully among erasing options. Enforcement: Static, Design

New Guideline 22 – Ensure allocator conventions and restrictions are conformed to.

Enforcement: Static, Design

New Guideline 23 - Specify comparison types for associative containers of pointers and

iterators. Enforcement: Static, Design

New Rule 24 - Make sure destination ranges are big enough. Enforcement: Static & Dynamic,

Design & Coding

New Rule 25 - Avoid remove-like algorithms on containers of pointers. Enforcement: Static,

Design

New Rule 26 – Never dereference an invalid iterator. Enforcement: Static & Dynamic, Design &

Coding

New Rule 27 – Always check and ensure compliance with the pre-conditions for STL

functions. Enforcement: Static & Dynamic, Design & Coding

New Rule 28 – Only use the macro offsetof in <cstddef> with non-static POD types.

Enforcement: Static, Coding

Page 162: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

15-5

New Rule 29 – Do not use iterators to hold singular values. Enforcement: Static, Design

New Rule 30 – Operations on types used with the complex and valarray classes shall not

throw exceptions. Enforcement: Static, Design

New Rule 32– Avoid using operator[] to access STL containers, use iterators instead.

Enforcement: Static, Coding

Page 163: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-1

Appendix 16 – Programming Language Selection Pattern

Justification of Programming Language Selection PatternAuthor Derek W. Reinhardt

Created 09 July 2004 Last Modified 11 September 2004

Intent This pattern provides a framework for arguing the selection of programming language for safety

critical systems. The argument is based of numerous criteria that relate both to the language

specification and the environment in which the language is employed (people, process and tools).

The pattern recognises that few languages would be arguable purely on the language itself and that

tools play an important role in providing evidence to support the argument.

Also Known As • Programming Language Pattern

• Selection of Programming Language Pattern

Motivation This pattern was developed for the following reasons:

• To provide a framework for arguing the selection of the programming language for safety

critical systems.

• To allow the selection of the programming language to be justified within the context of

numerous standards including IEC61508, DO-178B, Defence Standard 00-55 Issue 2 and

Defence Standard 00-56 Issue 3.

Structure

G.TOP

{LangX} supports the

correct implementation of

{SystemY}'s software

design

G3.1.1

High quality, certified and/

or verified language

translators, analysis and

support tools are used for

{LangX}

S3.1

Argument that tools

used in development,

analysis and verification

of the design in {LangX}

are high quality and are

certified or verified

C.TOP.2

{SystemY} definition

C3.1A

Certification and

verification criteria

for tools

C3.1B

Definition of "high

quality"

G1.2

{LangX} features support

maintaining the

implementation over

{SystemY}'s operational

lifetime

S1

Argument over {LangX}

supporting the correct

implementation of the

design during initial

development and during

{SystemY}'s operational

lifetime

G1.1

{LangX} supports the

correct implementation of

the design during initial

development of {SystemY}

G2.1

{LangX} is well understood

by the programmers and

this supports the correct

implementation of the

design

S2

Argument over the

programmers' roles in

correctly implementing

{SystemY}'s software

design

S1.2

Argument over features

of {LangX} that support

maintaining the

implementation over

{SystemY}'s operational

lifetime

G1.2.1

{LangX} provides support

for user documentation

and comments

G1.2.2

Coding style guidelines for

{LangX} support

development consistency /

maintenance

S2.1

Argument that the

development team has

the expertise to develop

software in {LangX} for

{SystemY}'s design

G2.1.1

Development team has the

expertise to develop

software in {LangX} for

{SystemY}'s design

G1.2.3

{LangX} provides support

for other features that

maintain the correct

implementation of the

design over {SystemY}'s

operational lifetime

S1.1A

Argument over means of

preventing and/or

detecting errors

S1.1B

Argument over features

required by {LangX} in

order to implement the

design

G1.1A.1

Occurrences of errors in

the implementation of the

design in {LangX} are

prevented

G1.1A.2

Occurrences of errors in

the implementation of the

design in {LangX} are

detected

G1.1B

{LangX} supports

{FeatureZ} that is required

in order to correctly

implement the design

S3

Argument over the tools'

roles in correctly

implementing

{SystemY}'s software

design

G3.1

Tools for development in

{LangX} support the

correct implementation of

{SystemY}'s software

design

ref. Figure 16-3ref. Figure 16-2

A.TOP

{SystemY}'s software

design is shown to be

acceptably safe

elsewhere A

n-of-2

C.TOP.1

{LangX} definition

n

Figure 16-1: Top-Level Argument

Page 164: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-2

G1.1A.1.2

Occurrences of run-time

errors in the

implementation of the

design are prevented

S1.1A.1

Argument over

instances at which

errors that might occur

in the implementation of

the design

ref. Figure 16-4

G1.1A.1

Occurrences of errors in

the implementation of the

design in {LangX} are

prevented

G1.1A.1.1

Errors are not introduced

in the translation of the

implementation (source

code) into executables

A1.1A.1

Source code is

grammatically correct

from Figure 16-1

G1.1A.1.1.1.1

Fully verified and/or

formally proven compiler

is used for {LangX}

G1.1A.1.1.1

Errors in translation are

not possible

G1.1A.1.1.2

Translation errors are

possible, but those parts

of the translator are known

and avoided

G1.1A.1.1.2.1

Error prone translation

properties of a compiler

are well known and

documented

S1.1A.1.1

Argument over absence

and/or avoidance of

errors in the translation

G1.1A.1.1.2.2

Known error prone

properties of a compiler

are avoided

A

Figure 16-2: Error Prevention Argument

ref. Figure P-9G1.1A.2B.1

{LangX} has features to

restrict and manage

complexity

S1.1A.2B

Argument over types of

implementation features

that facilitate the

detection of errors in the

design

G1.1A.2A.2

{LangX} lends itself to

dynamic testing to

complement the static

analysis

S1.1A.2A

Argument to show that

errors in the design

would be detected

though analysing and

verifying the

implementation in

{LangX}

G1.1A.2A.1

{LangX} lends itself to a

significant proportion of

static analysis

ref. Figure 16-10 ref. Figure 16-11

G1.1A.2B.2

{LangX} supports

abstraction and

information hiding

G1.1A.2

Occurrences of errors in

the implementation of the

design in {LangX} are

detected

G1.1A.2B.3

{LangX} supports other

features that facilitate the

detection of errors in the

design

from Figure 16-1

Figure 16-3: Error Detection Argument

Page 165: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-3

G1.1A.1.2B.2A.1

{LangX} lends itself to the

application of defensive

programming techniques

G1.1A.1.2B.2B.1

Proven design patterns

are available for

{LangX}

G1.1A.1.2B.2B.2

{LangX} supports the

reuse of previously

verified code

from Figure 16-2

G1.1A.1.2B.1

Sources of commonly

introduced run-time errors

are identified and avoided

G1.1A.1.2B.2

{LangX} supports the

application of design

techniques that avoid and

mitigate run-time errors

S1.1A.1.2B.2A

Argument over {LangX}

features that avoid or

mitigate run-time errors

G1.1A.1.2

Occurrences of run-time

errors in the

implementation of the

design are prevented

S1.1A.1.2B

Argument over means of

avoiding, mitigating,

detecting and handling

non-definition related

errors at run-time

G1.1A.1.2A.1

Only completely and

unambiguously defined

aspects of {LangX} are

used for {System Y}

S1.1A.1.2A

Argument that no errors,

omissions or

inconsistencies relating

to {LangX}'s definition

will contribute to run-

time errors in the

implementation of the

design

ref. Figure 16-5

C1.1A.1.2A

{LangX} definition

G1.1A.1.2B.3

{LangX} supports a robust

run-time error detection

(or exception) system and

handling mechanism

G1.1A.1.2B.2A.2

{LangX} supports the

checking of assertions at

run-time

S1.1A.1.2B.2B

Argument over design

techniques that facilitate

the use of previously

verified code that is

known to contain no

run-time errors

ref. Figure 16-7

G1.1A.1.2B.2A.3

{LangX} supports other

features that avoid or

mitigate run-time errors

G1.1A.1.2B.2B.3

{LangX} supports other

features that facilitate the

use of previously verified

code that is known to

contain no run-time errors

Figure 16-4: Run-time Error Argument

G1.1A.1.2A.1A.1

Base language of

{LangX} has been

internationally

standardised

S1.1A.1.2A.1A

Argument that the

standardisation of

{LangX} eliminates

ambiguities relating to

variations in definition

G1.1A.1.2A.1B.1

{LangX} has no

unspecified, undefined,

indeterminate and

implementation defined

behaviours

G1.1A.1.2A.1B.2

A subset of {LangX}

sufficiently restricts the

unspecified, undefined,

indeterminate and

implementation defined

behaviours of {LangX}

G1.1A.1.2A.1A.2

Library support for

{LangX} has been

internationally

standardised

G1.1A.1.2A.1

Only completely and

unambiguously defined

features of {LangX} used

for {System Y}

S1.1A.1.2A.1B

Argument that only the

completely and

unambiguously defined

features of {LangX} are

to be used

ref. Figure 16-6

from Figure 16-4

Figure 16-5: Definition Argument

Page 166: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-4

G1.1A.1.2A.1B.2.1

Undefined behaviour of

{LangX} is identified and

restricted

G1.1A.1.2A.1B.2.2

Unspecified behaviour of

{LangX} is identified and

restricted

G1.1A.1.2A.1B.2.3

Implementation-defined

behaviour of {LangX} is

identified and restricted

G1.1A.1.2A.1B.2.4

Indeterminate behaviour

of {LangX} is identified

and restricted

G1.1A.1.2A.1B.2

A subset of {LangX}

sufficiently restricts the

unspecified, undefined,

indeterminate and

implementation defined

behaviours of {LangX}

from Figure 16-5

C1.1A.1.2A.1B.2

Definition of subset of

{LangX}

Figure 16-6: Behaviours Subset Argument

G.SIDE_EFFECT.1

{LangX} is not prone to

side effects in expression

G.MISTAKES

{LangX} has features to

facilitate the detection of

programming typos and

unintentional mistakes

G.JUMPS.1

{LangX} supports a

modular, structured

approach (restrictions on

jumps between scopes)

G.VARIABLES.1

Declaration and

initialisation of variables is

explicit

G.TYPE.1

{LangX} is strongly typed

to ensure type safety and

to avoid type related

errors at run-time

ref. Figure 16-9

G.VARIABLES

Uninitialised and implicitly

initialised variables that

are a likely source of error

at run-time are avoided

G.SIDE_EFFECT

Side effects in expression

that are a likely source of

error at run-time are

avoided

G.MISTAKES

Unintentional

programming mistakes

that are a likely source of

run-time error are avoided

S1.1A.1.2B.1

Argument across the

identified sources of

commonly introduced

run-time errors

G.JUMPS

Jumps between scopes

that are a likely source of

error in an implementation

of a design are avoided

G.TYPE

Type related features that

are a likely source of error

at run-time are avoided

G.PARADIGM.1

{LangX}'s implementation

of the paradigm's features

is error free

G1.1A.1.2B.1

Sources of commonly

introduced run-time errors

are identified and avoided

J1.1A.1.2B.1

Identified sources of

commonly introduced

run-time error are

adequate

G.PARADIGM

Paradigm related sources

of commonly introduced

run-time errors are

avoided

G1.1A.1.2B.1.1

Data related sources of

commonly introduced run-

time errors in an

implementation are

restricted

G1.1A.1.2B.1.2

Control flow related

sources of commonly

introduced run-time errors

in an implementation are

restricted

from Figure 16-4

G1.1A.1.2B.1.4

Resource availability

related sources of

commonly introduced run-

time errors in an

implementation are

restricted

G.MEMORY

Memory allocation/

deallocation activities that

are a likely cause of error

in an implementation of a

design are avoided.

G.MEMORY.1

{LangX} is not prone to

memory leaks

G.MATH

Mathematical operations

and results that are a

likely source of error at

run-time are avoided

G.MATH.1

{LangX} is not prone to

invalid mathematical

operations and results

G1.1A.1.2B.1.5

Other sources of

commonly introduced run-

time errors in an

implementation of a

design are restricted

ref. Figure 16-8

G1.1A.1.2B.1.3

Run-time exceptions

leading to abnormal

program termination in an

implementation are

restricted

J

Generic language argument

shall address all relationships.

Some relationships may be

simplified in relation to the

specific design context of

{SystemY}.

Figure 16-7: Common Error Sources Argument

Page 167: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-5

G1.1A.1.2B.1.5.2

Language constructs or

library functions that are

known to be prone to

misunderstanding or being

misused are restricted

S1.1A.1.2B.1.5

Argument that other

misused, misunderstood

and prone to error

{LangX} features are

known and restricted

G1.1A.1.2B.1.5.1

Language constructs or

library functions that are

prone to misunderstanding

or being misused are well

known and documented

G1.1A.1.2B.1.5

Other sources of

commonly introduced run-

time errors in an

implementation of a

design are restricted

from Figure 16-7

Figure 16-8: Other Error Sources Argument

G1.1A.1.2B.1.1.1.1.3.1

{LangX} principally

supports static types,

including sub-types and

enumerations

G1.1A.1.2B.1.1.1.1.1.1

Implicit conversions are

not allowed

G1.1A.1.2B.1.1.1.1.3.2

Types including user

defined types are statically

analysable

G1.1A.1.2B.1.1.1.1.1.2

Explicit conversions are

permitted only where

justifiably necessary

G1.1A.1.2B.1.1.1.1.2.2

Access types and pointers

should only be permitted

where justifiably

necessary

G1.1A.1.2B.1.1.1.1.2.1

{LangX} supports the

checking of array bounds

G1.1A.1.2B.1.1.1.1.4

Types in {LangX} are

checkable at run time

G1.1A.1.2B.1.1.1.1

{LangX} is strongly typed

to ensure type safety and

to avoid type related

errors at run-time

from Figure 16-7

S1.1A.1.2B.1.1.1.1

Argument across

features that make a

language strongly typed

G1.1A.1.2B.1.1.1.1.1

Type conversions in

{LangX} are controlled

G1.1A.1.2B.1.1.1.1.2

Access to types in {LangX}

is controlled

G1.1A.1.2B.1.1.1.1.3

Types in {LangX} are

statically analysable

Figure 16-9: Strongly Typed Argument

Page 168: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-6

G1.1A.2A.1A.1

Use of dynamic variables

is restricted except where

justifiably necessary

G1.1A.2A.1B.3.1

{LangX} lends itself to

control flow, data flow, and

information flow analysis

G1.1A.2A.1B.1

{LangX}'s run-time

resource usage is

analysable and

predictable

G1.1A.2A.1A.3

Use of recursion is

restricted except where

justifiably necessary

G1.1A.2A.1A.2

Use of interrupts is

restricted except where

justifiably necessary

G1.1A.2A.1A

{LangX} features that

inhibit the capabilities of

static analysis are

restricted

G1.1A.2A.1B.3.2

{LangX} support the use of

assertions/annotations in

analysing preconditions,

postconditions and

invariants

G1.1A.2A.1

{LangX} lends itself to a

significant proportion of

static analysis

from Figure 16-3

S1.1A.2A.1A

Argument over a

restriction on those

features of {LangX} that

inhibit static analysis

G1.1A.2A.1B.3.4

{LangX} lends itself to

symbolic execution

G1.1A.2A.1B.2

{LangX}'s temporal

behaviour is analysable

and predictable

G1.1A.2A.1B.3

{LangX}'s functional

behaviour is analysable

and predictable

G1.1A.2A.1B.3.3

{LangX} lends itself to

formal code verification

(formal methods)

S1.1A.2A.1B

Argument that {LangX}

is predictable and that it

lends itself to static

analysis

S1.1A.2A.1C

Argument that static

analysis of {LangX}

meets the relevant

standards

G1.1A.2A.1C

Static analysis of {LangX}

meets the relevant

standards

C1.1A.2A.1

Definition of "significant

proportion"

C1.1A.2A.1C

Identified relevant

standards

G1.1A.2A.1A.4

Use of other {LangX}

constructs that inhibit the

capabilities of static

analysis is restricted

S1.1A.2A.1B.3

Argument over means of

analysing {LangX}'s

functional behaviour

n-of-4/5

G1.1A.2A.1B.3.5

Other means of analysing

{LangX}'s functional

behaviour are used

Figure 16-10: Static Analysis Argument

G1.1A.2A.2

{LangX} lends itself to

dynamic testing to

complement the static

analysis

G1.1A.2A.2A.2

{LangX}'s run-time

resource usage is testable

and predictable

G1.1A.2A.2A.1

{LangX}'s temporal

behaviour is testable and

predictable

G1.1A.2A.2A.3

{LangX}'s functional

behaviour is testable and

predictable

S1.1A.2A.2B

Argument that dynamic

testing of {LangX} meets

the relevant standards

G1.1A.2A.2B

Dynamic testing of

{LangX} meets the

relevant standards

S1.1A.2A.2A

Argument that

appropriate aspects of

{LangX}'s behaviour are

dynamically testable.

C1.1A.2A.2A

Identified coverage and

limitations of the statically

analysable aspects of

{LangX}

from Figure 16-3

C1.1A.2A.2B

Identified relevant

standards

Figure 16-11: Dynamic Testing Argument

Page 169: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-7

Participants The following participant descriptions include additional information to those described in Figures

16-1 to 16-11.

Figure 16-1 G1.1B Claims that {Lang X} supports a {FeatureZ} that is required in order to

correctly implement the design. These features may include such things

as support for interfacing to modules written in other languages, and

concurrency or parallel processing.

G1.2 Claims that {Lang X}’s features support maintaining the

implementation over {System Y}’s operational lifetime by ensuring that

the decisions of the initial development are clearly communicated to

future maintainers.

Figure 16-2 G1.1A.1.1.2

G1.1A.1.1.2.1

G1.1A.1.1.2.2

Claims that errors in translation are possible, but those parts of the

translator are known and avoided. For example, code optimisation is a

possible source of error in a translator.

Figure 16-3 S1.1A.2A Identifies the approach that errors in the design will be detected through

analysing and verifying the design. This pattern recognises that static

analysis is not applicable to all situations.

Figure 16-5 S1.1A.1.2A.1A Identifies the approach that the standardisation of {Lang X} eliminates

ambiguities relating to variations in definition. For example, prior to

official standardisation various draft language definitions may be

available.

Figure 16-7 J1.1A.1.2B.1 Justifies that the identified sources of commonly introduced run-time

errors are adequate. This is because the error types (data, control flow,

run-time exceptions/terminations and resource availability) can be

associated in totality with the language properties (strongly typed,

variable initialisation, side effects, etc.).

Collaborations This pattern is structured on the following key arguments:

• Argument over {Lang X} supporting the correct implementation of the design – S1

• Argument over the programmers’ roles is correctly implementing the design – S2

• Argument over the tools’ roles in correctly implementing the design – S3

There are collaborations between the tools argued under S1 and the tools argued under S3.

Importantly the certification and verification criteria C3.1A will therefore have an impact on the

evidence provided in arguing S1.

There are also collaborations between the errors and techniques argued under S1 and the

programmers’ argued under S2. This implicitly implies that programmers argued under S2 should

have a detailed knowledge as to how the correct implementation is supported under S1.

At a lower level there are collaborations between the error prevention argument (G1.1A.1) and

error detection argument (G1.1A.2). Particular focus should be given to detecting errors for which

the prevention is weak and preventing errors for which the detection capability is weak.

At a slightly lower level there are collaborations between the static analysis (G1.1A.2A.1) and the

dynamic testing (G1.1A.2A.2). The argument is structured such that both forms of analysis and

verification are complementary to each other. Thus if both goals are satisfied then this implicitly

implies that all desired properties of the software are known.

Figure 16-7 presents a complex set of relationships between error types and language

characteristics. Thus there are significant collaborations between the two levels of the argument

here also. These goals are further addressed under the implementation section of this pattern.

Applicability This pattern is applicable where the safety case is required to justify the selection of programming

language for use in the safety critical system.

In order to instantiate this pattern the following contextual information is required:

• {Lang X} definition, including reference to the standard and any subset that is to be applied –

C.TOP1, C1.1A.1.2A, C1.1A.1.2A.1B.2

• {System Y} definition, including design, application and domain – C.TOP2

• Certification and verification criteria for tools – C3.1A (likely to come directly from standards

or from requirements imposed by clients or regulators)

• “High quality” tools definition, and ideally this will be a tool that does not contribute to the

errors argued under G1.1 and G1.2. – C.3.1B (likely to be interpreted from the standards or

Page 170: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-8

defined internally within the context of ISO9000)

• “Significant proportion” of static analysis definition – C1.1A.2A.1 (likely to be defined based

on achieving the required verification confidence)

• Identification of relevant standards – C1.1A.2A.1C, C1.1A.2A.2B

• Identification of the coverage and limitations of the statically analysable aspects of {Lang X} –

C1.1A.2A.2A (likely to be defined based on achieving the require verification confidence)

Consequences After instantiating this pattern, a significant number of unresolved goals will remain to be

instantiated and developed. This activity is intended to be carried out for a particular language (or

language subset) choice. Note that for most languages the unresolved goals will not be resolved

through the language alone, and additionally a combination of tools will be required. The goals

requiring further development or instantiation are as follows. Refer to Figures 16-1 to 16-11 and

the participants section for the respective definitions.

• Translator: G1.1A.1.1.1.1, G1.1A.1.1.2.1, G1.1A.1.1.2.2

• Language standardisation: G1.1A.1.2A.1A.1, G1.1A.1.2A.1A.2

• Language behaviour: G1.1A.1.2A.1B.1, G1.1A.1.2A.1B.2.1, G1.1A.1.2A.1B.2.2,

G1.1A.1.2A.1B.2.3, G1.1A.1.2A.1B.2.4

• Strong types: G1.1A.1.2B.1.1.1.1.1.1, G1.1A.1.2B.1.1.1.1.1.2, G1.1A.1.2B.1.1.1.1.2.1,

G1.1A.1.2B.1.1.1.1.2.2, G1.1A.1.2B.1.1.1.1.3.1, G1.1A.1.2B.1.1.1.1.3.2,

G1.1A.1.2B.1.1.1.1.4

• Run-time errors: G.VARIABLES.1, G.MATH.1, G.PARADIGM.1, G.MISTAKES.1,

G.SIDE_EFFECT.1, G.JUMPS.1, G.MEMORY.1, G1.1A.1.2B.1.5.1, G1.1A.1.2B.1.5.2

• Error avoidance and mitigation: G1.1A.1.2B.2A.1, G1.1A.1.2B.2A.2, G1.1A.1.2B.2A.3

• Code reuse: G1.1A.1.2B.2B.1, G1.1A.1.2B.2B.2, G1.1A.1.2B.2B.3

• Exception detection and handling: G1.1A.1.2B.3

• Features restricting static analysis: G1.1A.2A.1A.1, G1.1A.2A.1A.2, G1.1A.2A.1A.3,

G1.1A.2A.1A.4

• Static analysis: G1.1A.2A.1B.1, G1.1A.2A.1B.2, G1.1A.2A.1B.3, G1.1A.2A.1B.3.1,

G1.1A.2A.1B.3.2, G1.1A.2A.1B.3.3, G1.1A.2A.1B.3.4, G1.1A.2A.1B.3.5, G1.1A.2A.1C

• Dynamic testing: G1.1A.2A.2A.1, G1.1A.2A.2A.2, G1.1A.2A.2A.3, G1.1A.2A.2B

• Language features for preventing errors: G1.1A.2B.1, G1.1A.2B.2, G1.1A.2B.3

• Language features required by design: G1.1B

• Documentation, comments, coding style: G1.2.1, G1.2.2, G1.2.3

• Development team expertise: G2.1.1

• Tool quality: G3.1.1

Implementation Implementation of this pattern involves first instantiating all the contexts. This will involve

selecting the programming language for which the pattern will be instantiated. Users may wish to

familiarise themselves with the pattern prior to making the language selection, as this will ensure

they select a language for which a justifiable argument has potential to be supported.

Having established all the contexts, each of the main strategies should be examined (S1, S2, S3). In

attempting to satisfy S1, numerous decisions need to be made. These are as follows:

• The balance and types of static analysis and dynamic testing – G1.1A.2A.1, G1.1A.2A.2

• The balance of error prevention and detection – G1.1A.1 and G1.1A.2

• The number of features required by the design – G1.1B

• Whether to use a formally verified translator or to find the errors in an existing translator –

G1.1A.1.1.1, G1.1A.1.1.2

• Whether to use a completely and unambiguously defined language or to use a language

definition subset – G1.1A.1.2A.1B.1, G1.1A.1.2A.1B.2

• The static techniques to be applied to establish confidence in the software’s functional

behaviour – G1.1A.2A.1B.3.1, G1.1A.2A.1B.3.2, G1.1A.2A.1B.3.3, G1.1A.2A.1B.3.4

From these decisions, the lower level goals can be instantiated and developed where required.

These can then be built up to satisfy higher level goals and thus eventually satisfying G.TOP.

Satisfying goals G1.1A.1.2B.1.1, G1.1A.1.2B.1.2, G1.1A.1.2B.1.3, G1.1A.1.2B.1.4, and

G1.1A.1.2B.1.5 is not a simple task. This is due to the complex relationships between subset

restriction categories (G.TYPE, G.VARIABLES, etc) and the data, control flow, run-time

exceptions and resource availability. The pattern recognises that absolute proof for these goals is

difficult and that the confidence deficit will often be established through static analysis and

dynamic testing.

Page 171: Use of the C++ Programming Language in Safety Critical Systemsread.pudn.com/downloads91/ebook/348435/Use of the C++... · 2007-10-21 · Use of the C++ Programming Language in Safety

16-9

Possible Pitfalls.

• Attempting to instantiate the pattern for a language that is immature and lacks a body of

knowledge on its application.

• Not recognising the importance of both static and dynamic testing.

• Not recognising the importance of both error prevention and detection.

• Not recognising the importance that the features provided by the language relate appropriately

to the design.

• Not recognising that, where a subset is used to restrict language features in order to satisfy the

lower level goals, a consideration is also required as to what proportion of the subset will

be auto-enforced.

• Not recognising that tools used to support lower level goal claims are likely to also require to

be addressed under S3.

• Underestimating the relationships between the restriction categories (G.TYPE,

G.VARIABLES, etc) and the data, control flow, run-time exceptions and resource

availability goals.

Example

Applications

This argument pattern can potentially be applied to any programming language, and has been

developed with appreciation for Ada, SPARK, C and C++. Specifically, groundwork has been

done in applying the pattern for the use of the C++ programming language in safety critical

systems.

Known Users This pattern has yet to be applied to a real world example.

Related Patterns • Fault Free Software Argument Pattern

• Diverse Argument Pattern

• Software Safety Case Patterns Catalogue

Table 16-1: Programming Language Selection Pattern