this is a translation of escr (embedded system ... preface in recent years, the scale of embedded...

183
176

Upload: phungphuc

Post on 08-Jun-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

176

ii

This is a translation of ESCR (Embedded System development Coding Reference) [C language edition] Version 1.1 published by IPA/SEC* in Japan. ESCR collects points to note and know-how for coding and organizes them as practices and rules, in order to improve the quality of the source code written in C language.

The purpose of the book is to be used as a reference to establish coding conventions in organizations and groups developing embedded software using C language, promoting the standardization of writing source code and uniformity of the source code quality.

March 2012Software Engineering Center, Technology Headquarters,

Information-technology Promotion Agency, Japan

Copyright (c) 2012, IPA/SECPermission to copy and distribute this document is hereby granted provided that this notice is retained on all copies, that

copies are not altered, and that IPA/SEC is credited when the material is used to form other copyright policies.

* Software Engineering Center, Technology Headquarters, Information-technology Promotion Agency, Japan

iii

Preface

In recent years, the scale of embedded software has been expanding and development by many people is becoming mainstream. In such development projects which have large teams consisting of engineers with various levels of skills, it becomes extremely necessary to take measures to balance out the differences of their skills. In particular, measures for creating high quality source code with consideration to safety, maintainability and portability from the software implementation’s standpoint independently from the engineers' skills are crucially important, and are regarded as the basic physical strength of embedded software development.

One effective means to address this issue is to prepare and utilize coding conventions where various coding expertise of the experienced are collected up as knowledge. This background led us to write and edit the "Coding Practices Guide" targeted for those establishing a coding convention for C language. In the development of this guide, the drafts were drew up by experts in programming techniques in the Implementation Quality Technical Committee of the Embedded Software Development Improvement and Promotion Task Force consists of members of the METI, IPA/SEC and related organizations.

This book is structured by practices categorized according to quality characteristics and their corresponding rules. We believe the information provided in this book will help to establish coding conventions that will meet users’ requirements.

Not only will this book be useful to engineers establishing coding conventions, but it will also serve as a stimulus for new ways of looking at things with an overview of the C language characteristics for experienced developers, and for beginners, as a practical textbook which will be impart the know-how acquired by their predecessors. We hope that use of this book will lead to improve embedded software productivity and to attain high quality software development.

March 2006Embedded Software Development Improvement and Promotion Task Force

Implementation Quality Technical Committee

iv Table of Contents

Preface.................................................................................................................................................................. iii

Part 1 How to Read the.Coding Practices Guide. 11 Overview ...................................................................................................... 2

1.1 What are Coding Practices? ............................................................................................ 2

1.2 Purpose and Position of Coding Practices and the Target Users .................................... 3

1.3 Characteristics of the Coding Practices ........................................................................... 4

1.4 Notes on Using this Guide ............................................................................................... 5

2 Understanding Source Code Quality ........................................................... 8

2.1 Quality Characteristics ..................................................................................................... 8

2.2 Quality Characteristics, and Code Practices and Rules ................................................ 12

3 How to Use this Guide ............................................................................... 14

3.1 Scenarios for Using this Guide ...................................................................................... 14

3.2 Creating New Coding Conventions .............................................................................. 15

3.3 Enhancing Existing Coding Conventions ....................................................................... 17

3.4 Learning Material for Training Programmers and Self-Study ........................................ 18

Part 2 Coding Practices for Embedded Software: Practices Chart. 19How to Read the Practices Chart......................................................................................... 20

Terminology in the Practices Chart...................................................................................... 23

Coding Practices for Embedded Software........................................................................ 24

● Reliability..................................................................................................................................................................25

● Maintainability .......................................................................................................................................................55

● Portability...............................................................................................................................................................111

● Efficiency............................................................................................................................................................... 123

Table of Contents

vTable of Contents

Part 3 Typical Coding Errors in Embedded Software. 127Typical Coding Errors in Embedded Software ............................................... 128

1 Meaningless expressions and statements ....................................................................... 128

2 Wrong expressions and statements ................................................................................. 130

3 Wrong memory usage ...................................................................................................... 131

4 Errors due to misunderstandings in logical operations .................................................... 133

5 Mistakes due to typos ...................................................................................................... 134

6 Wrong descriptions that do not cause errors in some compilers ..................................... 135

...............Appendices. 137

Appendix A List of practices and rules .......................................................... 138

Appendix B Rule classification based on C language grammar ................... 152

Appendix C Documentation templates for implementation-defined items ..... 164

Citations and References .............................................................................................. 175

 

Part1How to Read the

Coding Practices Guide

1 Overview 1.1 What are Coding Practices?

1.2 Purpose and Position of Coding Practices and the Target Users

1.3 Characteristics of the Coding Practices

1.4 Notes on Using this Guide

2 Understanding Source Code Quality 2.1 Quality Characteristics

2.2 Quality Characteristics, and Coding Practices and Rules

3 How to Use this Guide 3.1 Scenarios for Using this Guide

3.2 Creating New Coding Conventions

3.3 Enhancing Existing Coding Conventions

3.4 Learning Material for Training Programmers and Self-Study

2 Part1 How to Read the Coding Practices Guide

1 Overview

1.1 What are coding pract ices?

Creating source code (code implementation) is an inevitable task for developing embedded soft-ware. Success or failure of this task greatly affects the quality of the resulting software . C language, most commonly used for embedded software development, is said to have greater flexibility in writ-ing code and thus tends to reveal differences of the engineers’ experiences. It is undesirable that the quality of source code varies depending on the engineer’s skills and experiences. To prevent such a situation, some innovative companies promote standardization of source code by establishing cod-ing standards or conventions to be followed by the organization or group.

Issues Regarding Coding Conventions

Generally, coding conventions are organized “styles (or rules) of writing code to be followed to maintain quality.” However, current coding conventions have the following issues.

1) The necessity for the rules is not understood. Or how to deal with rule violations appropriately is not un-derstood.

2) There are too many rules to learn. Or there are not enough rules to cover all the scope.3) Since there are not any precise tools to check compliance with rules, checking is left to engineers’ visual

examination, which is burdensome.

As a result, even in organizations or departments with established coding conventions, they have sometimes become meaningless and are not followed. Nevertheless, it is still good as long as some coding conventions are prepared regardless of their forms. Yet, there are many organizations which cannot establish the coding conventions and still depend on individual engineer’s decision in coding.

1.1 What are Coding Practices?

31●Overview

What are Coding Practices?

The “coding practices” in this guide aim to solve on-site issues related to coding conventions, and the basic way of thinking (basic concept) to be followed in various coding situations are organized as “practices” in consideration of software quality. This guide presents these practices and reference examples of related coding conventions (or rules).

Users of this book can solve previously stated issues for coding conventions by “establishing a concrete coding convention for their own department” in reference to such information.

Purpose and Position of Coding Practices

This book is a guide for coding practices intended to help creators or managers of coding conven-tions to establish them in companies or projects. The feature of this guide is that it considers coding conventions as “a way of writing code to be followed to maintain quality” and organizes the basic concept of rules as practices. The practices are broken down into their outlines and details based on the quality concept complied with “ISO/IEC9126-1:2001 Software Product Quality Part1: Qual-ity Model.” Further, rules for C language are presented to each practice with their necessity. These practices and rules aim to easily create practical “coding conventions” which can clarify their sig-nificance and necessity.

Target Users

This guide is written for the following users:

Creators of the Coding ConventionsThis guide can be used as a reference to create new coding conventions or to check and reorganize

existing coding conventions.

1.2 Purpose and Position of Coding Practices and Target Users

4 Part1 How to Read the Coding Practices Guide

Programmers and Program ReviewersHighly reliable and maintainable code can be produced with reasonable effort by understanding

and mastering the practices and rules in this guide.

Advantages Gained

By using this guide, the advantages mentioned above can be directly expected. As the result, the following advantages can further be expected:- Variations of implementation performance among engineers, which lead to a serious software

quality problem, can be resolved. - Obvious errors in source codes can be removed at early stages such as at the coding phase or subsequent reviews.

1.3 Character ist ics of the Coding Pract ices

The coding practices in this guide have the following characteristics.

Organized Practices and RulesThis guide considers that, code quality, like software quality, can be classified according to quality

characteristics such as “reliability,” “maintainability” or “portability,” and thus organizes the coding practices and rules systematically based on “ISO/IEC9126-1:2001 Software Product quality.” Prac-tices in this guide are customs and thoughts on implementation to maintain source code quality, and indicate the basic concepts of individual rules. The rules in this guide are presented in accordance with practices after thoroughly examining many existing coding conventions in the world and select-ing them to suit the current situation (actual situation of the language specification and processing systems). By classifying practices and rules according to quality characteristics, it is easy to under-stand which quality they are mainly aiming to maintain.

This guide refers to coding conventions used in companies to which the writers of the guide be-long, “MISRA C,” “Indian Hill C Style and Coding Standards” and “GNU coding standards” etc. For details, refer to the “Citations and References” at the end of the book.

1.3 Characteristics of the Coding Practices

51●Overview

Ready-to-use Reference RulesThis guide presents specific rules for C language as a reference to create coding conventions.

These rules are directly usable for coding conventions. By choosing the required rules and adding any further rules in reference to “3 How to Use this Guide,” a coding convention for C language will be easily created.

Presenting Necessity for RulesThis guide shows the necessity for rules in explanation of corresponding practices, examples of

rules, and their remarks. Rules considered to be well-known by experienced programmers are indi-cated as such in the “Preference guide”. Refer to it to consider the necessity.

Correspondence with Other Coding ConventionsFor most rules, this guide indicates the correspondence with the existing coding conventions

widely used. This makes it easier to check their inclusive relations. Coding conventions that have correspondence are “MISRA C,” “Indian Hill C Style and Coding Standards,” and others.

1.4 Notes on using this guide

Keep the following in mind when using this guide.

Scope of the Rules

In this guide, rules related to the following are not the reference rules for C language.

- Library functions- Metrics (numbers of lines in functions/complexity of functions, etc.)- Errors in writing possibly classified as coding errors

1.4 Notes on Using this Guide

6 Part1 How to Read the Coding Practices Guide

Although “Errors in writing possibly classified as coding errors” is excluded from the reference rules, examples of coding errors collected during writing this guide are presented in “Part 3 Typical Coding Errors in Embedded Software.” These errors are likely to be made by those new to C lan-guage. C language beginners are encouraged to read this part as it serves as a useful reference. Some projects may judge that it is better to include such coding error-like mistakes into rules. In that case, reference to examples in Part 3 will be a good help.

Standards Cited and Referenced in this Guide

This guide includes citations and references to the following standards.

C90The C language standard defined in “ ISO/IEC 9899:1990 Programming Language C.” It is of-

ten called “C90” as ISO/IEC 9899:1990 was published in 1990. The C language standard has been revised and is now C99, so C90 is an old version. However, C90 is still widely used , and there are not so many additional features in the revision, this guide uses C90 as the language standard. For changes from C90 to C99, refer to the Forward of “ISO/IEC 9899:1999 Programming Language-C.”

C99The C language standard defined in “ ISO/IEC 9899:1999 Programming Language C.” It is the

current C language standard. Since the original ISO/IEC 9899:1999 was published in 1999, it is of-ten called “C99.”

C++The C++ language standard defined in “ISO/IEC 14882:2003 Programming Language C++.”

71●Overview

MISRA CThe name for MISRA-C:1998 and MISRA-C:2004 defined by The Motor Industry Software Reli-

ability Association (MISRA) of UK .

MISRA-C:1998

The convention in Citations and References [5] defined by the MISRA of UK.

MISRA-C:2004

The convention in Citations and References [6] defined by the MISRA of UK. Revised edition of MISRA-C:1998.

Naming Conventions for Variable and Function

This guide uses as simple notation as possible for variable and function names, etc. shown in ex-ample code not to hinder understanding of the rules.

8 Part1 How to Read the Coding Practices Guide

2 Understanding Source Code Quality

2.1 Quality Characteristics

For many, speaking of software quality would remind them of “bugs.” However, in the field of software engineering, the quality of software for products is grasped as a broader concept. This qual-ity concept in software products is embodied in ISO/IEC9126.

ISO/IEC9126 and Source Code Quality

ISO/IEC9126-1 defines six characteristics (quality characteristics) related to software product quality: “reliability,” “maintainability,” “portability,” “efficiency,” “functionality,” and “usability.”

The two characteristics of “functionality” and “usability” among them are regarded to be con-sidered at earlier stages before the design phase. Whereas, the four characteristics of “reliability,” “maintainability,” “portability,” and “efficiency” are thought to be strongly tied to source code relat-ing stages.

Therefore, the practices provided in this guide adopt these four characteristics as a major classifi-cation. Table 1 shows the relationship between the “main quality characteristics” of ISO/IEC9126-1 and “code quality” proposed in this guide, together with “quality subcharacteristics.”

2.1 Quality Characteristics

92●How to grasp source codes quality

Table 1 Quality characteristics of software and code quality

Quality Characteristics (ISO/IEC9126-1)

Quality Subcharacteristics (ISO/IEC9126-1)

Code Quality

Reliability

The capability of the software product to maintain a specified level of performance when used under specified conditions.

Maturity The capability of the software product to avoid failure as a result of faults in the software.

Low occur-rence of bugs when the software is used for a long time.

Fault Toler-ance

The capability of the software product to main-tain a specified level of performance in cases of software faults or of infringement of its specified interface.

Tolerance to bugs and inter-face violations, etc.

Recoverability The capability of the software product to re-establish a specified level of performance and recover the data directly affected in the case of a failure.

Reliability Compliance

The capability of the software product to adhere to standards, conventions or regulations relating to reliability.

Maintainability

The capability of the software product to be modified. Modifi-cations may include corrections, improve-ments or adaptation of the software to changes in environ-ment, and in require-ments and functional specifications.

Analysability The capability of the software product to be diagnosed for deficiencies or causes of failures in the software, or for the parts to be modified to be identified.

Ease of under-standing the code.

Changeability The capability of the software product to enable a specified modification to be implemented.

Ease of modi-fying the code.

Stability The capability of the software product to avoid unexpected effects from modifications of the software.

Limited influ-ence due to modifications.

Testability The capability of the software product to enable modified software to be validated.

Ease of testing and debugging the code after modificaition.

Maintainability Compliance

The capability of the software product to adhere to standards or conventions relating to maintain-ability.

10 Part1 How to Read the Coding Practices Guide

Quality Characteristics (ISO/IEC9126-1)

Quality Subcharacteristics (ISO/IEC9126-1)

Code Quality

Portability

The capability of the software product to be transferred from one environment to another.

Adaptability The capability of the software product to be adapted for different specified environments without applying actions or means other than those provided for this purpose for the software considered.

Ease of adapting to different environments (including conformance to standards).

Installability The capability of the software product to be installed in a specified environment.

Co-existence The capability of the software product to co-exist with other independent software in a common environment sharing common resources.

Replaceability The capability of the software product to be used in place of another specified software product for the same purpose in the same environment.

Portability Compliance

The capability of the software product to adhere to standards or conventions relating to portability.

Efficiency

The capability of the software product to provide appropriate performance, relative to the amount of resources used, under stated conditions.

Time Behav-iour

The capability of the software product to provide appropriate response and processing times and throughput rates when performing its function, under stated conditions.

Efficiency with regard to processing time.

Resource Utili-sation

The capability of the software product to use appropriate amounts and types of resources when the software performs its function under stated conditions.

Efficiency with regard to resources.

Efficiency Compliance

The capability of the software product to adhere to standards or conventions relating to efficiency.

112●How to grasp source codes quality

Quality Characteristics (ISO/IEC9126-1)

Quality Subcharacteristics (ISO/IEC9126-1)

Code Quality

Functionality

The capability of the software product to provide functions which meet stated and implied needs when the software is used under specified conditions.

Suitability The capability of the software product to provide an appropriate set of functions for specified tasks and user objectives.

Accuracy The capability of the software product to provide the right or agreed results or effects with the needed degree of precision.

Interoperabil-ity

The capability of the software product to interact with one or more specified systems.

Security The capability of the software product to pro-tect information and data so that unauthorised persons or systems cannot read or modify them and authorised persons or systems are not denied access to them.[ISO/IEC 12207: 1995]

Functionality Compliance

The capability of the software product to adhere to standards, conventions or regulations in laws and similar prescriptions relating to functionality.

Usability

The capability of the software product to be understood, learned, used and attractive to the user, when used under specified conditions.

Understand-ability

The capability of the software product to enable the user to understand whether the software is suitable, and how it can be used for particular tasks and conditions of use.

Learnability The capability of the software product to enable the user to learn its application.

Operability The capability of the software product to enable the user to operate and control it.

Attractiveness The capability of the software product to be at-tractive to the user.

Usability Compliance

The capability of the software product to adhere to standards, conventions, style guides or regula-tions relating to usability.

12 Part1 How to Read the Coding Practices Guide

2.2  How to th ink qua l i t y charac te r i s t i c s , and code p rac t i ces and ru les

Overall Structure

This guide organizes the basic matters to be followed when creating source code as “practices.” For each “practice,” it introduces particular matters to be noted for reference information when writ-ing source code as “rules.” This guide classifies and arranges “practices” and “rules” in relation to the four quality characteristics shown in 2.1. The meaning of practice and rule in this guide are as follows (see Figure 1):

PracticePractices are customs or ways of thinking for implementations to maintain source code quality

and they indicate the basic concept of individual rules. They are broken down into practices in out-line and in detail.

RuleEach rule is an individual specific agreement to be followed and constitutes a coding convention.

This guide presents them as reference information.

Correspondence of Practices and RulesMost practices and rules are related to multiple quality characteristics, but each of them is clas-

sified into the most strongly related characteristic. Associating practices with quality characteristics makes it possible to understand how each practice strongly affects the particular quality.

2.2 Quality Characteristics, and Coding Practicesand Rules

132●How to grasp source codes quality

Declare variables used only in one function within that function

Functions called only from the functions defined in the identical file shall be static

The number of lines per file shall be within 1000 lines.

Coding convention for each project

added for their own

Practices: Concept for specific implementation to be followed to improve quality.

Rules:Reference information of specific coding rules in consideration of language dependency

Write in a way so as not to cause modification errors.

Write in a consistent way.

Write with careful attention to resource and time efficiencies.

・・・

Clarify the grouping of structured data and blocks.

Localize access ranges and related data. ・・・

・・・・・・

The body of if, else if, else, while, do, for, and switch statements shall be made into blocks.

Variables used only in one function shall be declared within the function.

Functions that are called only by functions defined in the same file shall be as static.

Reliability Portability EfficiencyMaintainability

Initialize areas and use them in con sideration of their sizes.

Write in a compiler independent way.

Use the rules as referencePractices O

verviewPractices in details

Quality Concepts

Language independent (with the exception of som

e partially dependent)Language dependent

Figure1. Relationship among quality concepts, practices, and rules

14 Part1 How to Read the Coding Practices Guide

3 How to Use this Guide

Usage Scenarios

This guide aims to support establishing coding conventions, and assumes the following three sce-narios for its usage.

1) Creating new coding conventions 2) Enhancing existing coding conventions 3) Learning material for training programmers and self-study

Creating new coding conventionsIf organizations or departments currently do not have coding conventions to be followed, this

guide can be used as a reference to establish a coding convention suitable for them.

Enhancing existing coding conventionsEven for organizations or departments with coding conventions developed, it is effective to main-

tain them regularly. In such a case, reference of this guide will be helpful in reviewing their contents more efficiently.

Learning Material for Training Programmers and Self-StudyThere are many books on C language. Unlike those existing books, this guide provides a way to

create source code to maintain and improve quality by focusing on the quality in implementation. In this sense, this guide can also be used as an excellent material to learn source code quality from a more practical point of view.

3.1 Scenarios for Using this Guide

153●How to use this guide

This section presents the procedure for a project without any coding conventions to create a new coding convention using this book.

When to Create

Coding conventions should be established before the program design stage. While a coding con-vention is a group of rules that are referred to during coding, some rules such as naming conventions for functions are associated with program design. Therefore, they should be decided before the pro-gram design phase.

How to Create

It is recommended to establish a new coding convention in the following order:

Step-1 Determine a development policy for the coding conventionStep-2 Choose rules based on the development policy determinedStep-3 Define the project dependent parts of the rulesStep-4 Determine the procedure to set exceptions for rule application

Afterward, add any rules if needed.

Step-1 Determine a development policy for the coding conventionIn developing a coding convention, a development policy for the coding convention should be de-

termined first. The development policy defines how the code produced in the project should be writ-ten based on the characteristics of the software developed in the project and members of the project. The policy here, for example, decides to focus on security and avoid unsafe features even if they are convenient, or to use unsafe features with care. When determining the policy, the quality characteris-tics valued in the project and the following viewpoints should be considered.

- Coding for fail-safe- Coding for easy to read programs- Coding for easy to debug

etc.

3.2 Creating New Coding Conventions

16 Part1 How to Read the Coding Practices Guide

Step-2 Choose rules based on the development policy determinedAccording to the development policy determined in Step-1, rules are chosen from the practices

chart in Part 2. For example, if the policy values portability, efforts such as to choose many rules that fall under the portability should be made.

In “Part 2 Coding Practices for Embedded Software” of this guide, rules considered seriously to impair the quality characteristics the rule belonged to if not adopted as convention are indicated by ○ in the “Preference guide” field. On the other hand, rules that may not be necessary as convention for those very familiar with the C language specification are indicated by ●. Use these marks as a guide for choosing rules. The easiest way to choose rules is to choose only the rules indicated by “○”. It will help to choose the most common rules.

Step-3 Define the project dependent parts of the rulesThere are three kinds of rules in this guide.

1) Rules that can be used as conventions without change (Rules without mark in the Rule speci-fication field)

2) Rules that need to be chosen from several alternatives according to the project characteristics (Rules with “Preference” mark in the Rule specification field)

3) Rules that need to be specified by documentation (Rules with “Definition” or “Documentation” mark in the Rule specification field)

The rules of 2) and 3) cannot be used as they are. When a rule of 2) is adopted, choose one from the alternatives listed. When a rule of 3) is adopted, specify the rule in reference to the explanation for each rule as a guide to rule definition.

Step-4 Determine the procedure to set exceptions for rule applicationDepending on the functionality being implemented, the quality characteristics to be focused at

coding time may differ (for example, efficiency should have higher importance than maintainabil-ity). In that case, writing code compliant with defined rules may cause problems such as prevention of achieving goals. To deal with such a situation, it is necessary to have a procedure to allow excep-tions partly for applications of rules.

What is important is to describe what problems may occur by writing code compliant with the rules, to have experts review the contents, and to record the result. Be sure to avoid allowing excep-tions too easily, which would cause rules to lose substance.

The following is an example of a procedure to allow exceptions.

173●How to use this guide

[An example of the procedure] (1) Write a form describing the reason for the exception.

(Example items for the form: “rule number,” “location (file name, line number),” “prob lems with the rule compliance,” “influence of deviating from the rule,” etc.)

(2) Have experts review the contents. → Put the review result in the form.(3) Receive approval from a person in charge of the coding stage → Record the approval in the form.

3.3 Enhancing exist ing coding convent ions

For projects with existing coding conventions, this guide can be used as a reference to enhance their contents.

Preventing Oversights and Omissions

By classifying the rules in existing coding conventions based on the concept of practices in this guide, overlooked or omitted aspects can be enhanced, or where the project put importance to carry out the task can be seen in a fresh light.

Clarifying the Necessity for Rules

By referring to practices and compliant examples of rules presented, this guide will be a useful tool to understand the necessity for rules that were forced to follow without knowing why.

3.3 Enhancing Existing Coding Conventions

18 Part1 How to Read the Coding Practices Guide

3.4 Learning material for trand for self- study

This guide is a good learning material for programmers who have studied C language but require more practical coding or have a little experience.

Target Users

This guide is for the following programmers:

- Programmers who have studied basic C language - Programmers who have experience in other programming languages but are beginners in C

language

What You Can Learn

By reading this guide, which is organized from the viewpoints of characteristics such as reliabil-ity, maintainability and portability, the following can be learned:

- Coding methods to improve reliability - Coding methods to avoid bugs - Coding methods to write code easy to debug and test.- Coding methods to write code easy to read for others, and their necessity

3.4 Learning Material for Training Programmers and Self-Study

Part 2Coding Practices

for Embedded Software: Practices Chart

- How to Read the Practices Chart

- Terminology in the Practices Chart

- Coding Practices for Embedded Software

● Reliability ● Maintainability ● Portabilitye ● Efficiency

20 Part2_Coding Practices for Embedded Software:Practices Chart

How to Read the Pract ices Char t

Organization of the Practices

Coding practices shown in Part 2 are classified according to the four characteristics (reliability, maintainability, portability, efficiency) among the software quality characteristics.

Practices in OutlinePractices closely related to each characteristic are further classified as practices in outline. For

maintainability, for example, there are five practices in outline from "Maintainability 1: Keep in mind that others will read the code" to "Maintainability 5: Write in a way easy to test."

Practices in detail For each practice in outline, there are several specific practices (practices in detail) collected. The

practice in outline "Maintainability 3: Write simple codes", for example, has four practices in detail as follows:

  Maintainability 3.1 Do structured programming.

  Maintainability 3.2 One statement should have one side effect.

  Maintainability 3.3 Separately describe expressions with different purposes.

  Maintainability 3.4 Do not use complicated pointer operations.

Structure of the Practices Chart

For each practice, reference information for rules to be noted during actual coding is provided in the chart. Each field in the chart presents the following information:

How to Read the Practices Chart

21

2726

1

1

Reliability1● R1_nitialize areas and use them in consid eration of their sizes.Part2_Coding Practices for Embedded Software:Practices Chart

Reliability

Rel

iabi

lityInitialize areas and use them in

consideration of their sizes.

Reliability

1

Various variables are used in programs written in C language.

Without considering areas reserved on computers and ensuring initialization of the areas when using

these variables may cause unexpected malfunction.

Pointers of C language should also be used in consideration of the areas pointed to.

Particular caution should be paid when using pointers as their misuse may cause serious problems to the

entire system.

Reliability 1.1 Use areas after initializing them.

Reliability 1.2 Describe initializations expressed without excess or

Reliability 1.3 Pay attentions to the range pointed by a pointer.

Rliability

1.1  Use areas after initializing them

Automatic variables shall be initialized at the time of declaration or the initial values shall be assigned just before using them.

R1.1.1 Preference guide  

Rule ecification

void func() { int var1 = 0; /* Initialize at the declaration*/ int i; var1++; /* Assign the initial value just before using it*/ for (i = 0; i < 10; i++) { … }}

If automatic variables are not initialized, their values become undefined and the computation results may differ

depending on environments. The initialization should be either at declaration or just before using the variable.

const variables shall be initialized at the time of declaration.

R1.1.2

const variables should be initialized at the declaration as the values cannot be assigned later on. If not initialized,

0 will be assigned for external variables and undefined values for automatic variables, so it may result in

unexpected behavior. Note that missing initialization at the declaration does not cause a compile error.

Note With C++, uninitialized const is a compile error.

[Related rules]

M1.11.1, M1.11.3

Rliability

1.1 Use areas af ter ini t ia l iz ing them

Preference guide  

Rule ecification

Compliant example Non-compliant example

Non-compliant exampleCompliant example

① Quality conceptQuality concepts are related to the main quality characteristics of “ISO/IEC9126-1.” This guide

uses the following four quality concepts:

  Reliability   Maintainability   Portability   Efficiency

② Practice Practices are those to be followed by programmers during coding.

- In outline ― Definition of a general concept for the practice. Independent from programming languages.

- In detail ― Details for a practice of general concept that should be noted more specifically. Like practice in outline, it is basically programming language independent, but some are stated as C language-specific.

③ Rule number Identification numbers of the rules.

① Quality concept② Practice in outline

⑤ Preference guid

⑦ Compliant example

⑧ Non-compliant

⑨ Remarks

⑥ Rule specification

② Practice in detail③ Rule number ④ Rule

How to Read the Practices Chart

example

22 Part2_Coding Practices for Embedded Software:Practices Chart

④ RulesSpecific reference rules for C language that correspond to a practice and must be followed. The

rule cited from MISRA-C:2004 is written in the following format.

Example: [MISRA 1.3]

⑤ Preference guideIt indicates whether or not to choose the rule when creating a coding convention using this guide.

No mark: Rules considered to be chosen according to the project characteristics.

● Rules considered unnecessary to be included in the convention for those very

familiar with he language specification (obvious for experienced programmers).

  ○ Rules considered to significantly impair the quality characteristics if not complied.

⑥ Rule specificationIt indicates whether it is necessary to define the details for the rule depending on the project

policy. It also indicates the rules specifying document creation (referred to as documentation rules), such as “record the behavior and usage of compiler-dependent language specification as a document,” although the rules themselves can be used as they are.

No mark: Rules not requiring detailed definition or documentation specification.

Choose: Rules required to be chosen from several alternatives listed. The alternatives are shown with numbers in parenthesis ((1), (2), ... ).

Define: Specific rules to be defined for each project. The part to be defined is enclosed by <<  >>.

Document: Rules requiring document creation. The part to be documented is enclosed by <<  >>.

⑦ Compliant exampleExample of source code written in compliance with the rule.

⑧ Non-compliant exampleExample of source code violating the rule.

⑨ RemarksNotes on C language specifications, the necessity for rules, problems that may be caused by

violation of rules, etc. are explained here.

23

Terminology in thechar t of prac ticesTerms used in the chart are explained as follows.

Term Meaning

Access Reference to variables or the reference with modification.

Type specifier Specifies a data type. There are two type specifiers, one that specifies basic types such as char, int and float and the other that specifies types defined with typedefs by the programmer for their own.

Type qualifier Adds specific attributes to types. There are two type qualifiers; const and volatile.

Storage class specifier Specifies the location where data are stored. There are four specifiers; auto, register, static, and exterm.

Boundary alignment Indicates methods for the compiler to allocate data into memory. For example, if int type is 2 bytes, be sure to allocate such data from an even address of the memory and not to allocate from an odd address.

Trigraph sequence Defined seguences of three characters such as ‘??=’, ‘??/’, ‘??(’for the compiler to replace with single character.‘??=’, ‘??/’, ‘??(’ are interpreted into ‘#’, ‘\’ , ‘[’ respectively.

Lifetime Duration that the references to a variable from the program is guaranteed after it is generated.

Multibyte character A character expressed by data of two or more bytes. Chinese characters, Japanese characters, and Unicode characters are included.

Null pointer A pointer that is not equivalent to any pointers that point to data or functions.

Null character A character that express the end of a string. Expressed with ‘\0’.

Scope A range where a variables etc. can be used.

File scope Scope is up to the end of the file.

Side effect Processing that cause changes to a state of execution environment. The following processings appliy: reference and change to volatile data, change to data, change to files, and function-calls that perform these operations.

Block A range that is enclosed with braces ‘{’, ‘}’ in data declarations and programs etc.

Enumeration type enum type. Constructed with several enumerated members.

Enumerator Members of an enumerated type (enum type).

Terminology in the Practices Chart

Terminology in the Practices Chart

24 Part2_Coding Practices for Embedded Software:Practices Chart

組込みソフトウェア向けコーディング作法This part presents coding practices for embedded software. As explained carlier, the practices

are categorized according to viewpoints of four characteristics (quality concepts) of “reliability”, “maintainability”, “portability” and “efficiency” in reference to quality characteristics (ISO/IEC9126-1) required for software. This categorization is for convenience sake; some practices and rules are useful to improve both reliability and maintainability by following each of them.

Reliability R Practices to improve reliability of created software are grouped. Main points considered include: - Reduce problems during use of the software as much as possible. - Tolerance to bugs and interface violation.

Maintainability M Practices to create source code easy to modify and maintain are grouped. Main points include: - Understandability and modifiability of code. - Small influence when modifications are made. - Easily to check the modified code.

Portability P Practices to port a software created to operate under a certain assumed environment into another environment as efficiently as effieiently possible without error are grouped.

Efficiency E Practices to effectively utilize the performance or resources of the created software are grouped. Main points considered include: - Coding in consideration of processing time. - Coding in consideration of memory size.

  

Coding Practices for Embedded Software

  

ReliabilityA large number of embedded software is incorporated into prod-ucts and used in various situations in our life. Consequently, extremely high reliability is demanded for a lot of embedded soft-ware. Software reliability requires not to wrongly behave (not to cause a failure) as software, not to affect the functionality of the entire software and system in case of malfunctions, and to be able to promptly restore the software to a normal behavior after a mal-function occurs. At the source code level, the point to be noticed regarding soft-ware reliability is to be skillful to avoid coding that may cause such malfunctions as much as possible.

●Reliability 1: Initialize areas and use them in consider-ation of their sizes.

● Reliability 2: Use data in consideration of their ranges, sizes and internal representations.

●Reliability 3: Write in a way to ensure the behavior.

26 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

Initialize areas and use them in consideration of their sizes.

Reliability

1

Various variables are used in programs written in C language. Without considering areas reserved in the computer and ensuring initialization of the areas when using these variables, unexpected malfunctions may be caused.

Pointers in C language should also be used in consideration of the areas they point to. Particular caution should be paid when using pointers as their misuse may cause serious problems to the entire system.

“Reliability 1” consists of the following three practices.

Reliability 1.1 Use areas after initializing them.

Reliability 1.2 Describe initializations without excess or deficiency.

Reliability 1.3 Pay attentions to the range pointed by a pointer.

27Reliability1● R1_nitialize areas and use them in consid eration of their sizes.

1

Reliability

  Use areas after initializing them

Automatic variables shall be initialized at the time of declaration or initial values shall be assigned just be-fore using them.

R1.1.1

void func() { int var1 = 0; /* Initialize at the declaration */ int i; var1++; /* Assign the initial value just before using it*/ for (i = 0; i < 10; i++) { … }}

void func() { int var1; var1++; …}

const variables shall be initialized at the time of declaration.

R1.1.2

const int N = 10; const int N;

const variables should be initialized at the declaration as the values cannot be assigned later on. If not initialized, 0 will be assigned for external variables and the values are undefined for automatic variables, which may cause unexpected behavior. Note that missing initialization at the declaration does not cause a compile error.

Note With C++, uninitialized const is a compile error.

[Related rules] M1.11.1, M1.11.3

Compliant example Non-compliant example

Non-compliant exampleCompliant example

R1.1 Use areas after initializing them.

Preference guide ●

Rule Specification

Preference guide ●

Rule Specification

If automatic variables are not initialized, their values become undefined and the computation results may differ depending on environments. The initialization should be either at declaration or just before using the variable.

28 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

Describe initializations expressed without ex

Arrays with specified number of elements shall be initialized with values that match the number of the elements.

R1.2.1

char var[] = "abc"; - or -char var[4] = "abc";

char var[3] = "abc";

Initializing an array with a string will not cause an error at declaration even if a space for a null charac-ter is not ensured in the array size. This is not a problem if described intentionally. However, when the array is used as an argument for a string handling function etc., the absence of a null character indicating the end of the string is more likely to cause unexpected behaviors. When initializing a string, it is neces-sary to ensure a space for the null character at the end.

[Related rule] M2.1.1

Initialization of enumerated type (enum type) mem-bers shall be one of the followings: not to specify constants at all, to specify all constants, or to spec-ify the first member only.

R1.2.2

/* Different values are assigned from E1 to E4 */enum etag { E1=9, E2, E3, E4 };enum etag var1;var1 = E3;/* E3 of var1 will never be equal to E4 */if (var1 == E4)

/* Both E3 and E4 become 11 without intention */enum etag { E1, E2=10, E3, E4=11 };enum etag var1;var1 = E3;/* E3 and E4 are equal, and the following will be true against the intention */if (var1 == E4)

If initial values are not specified to members of the enumerated type, they will be the value of the previ-ous member plus 1 (the value of the first member is 0). If some initial values are specified while others are not, the same value may unintentionally be assigned, which may cause unexpected behavior. To avoid the same value being assigned, initialization of the members should be one of not to specify con-stants at all, to specify all constants, or to specify for only the first member, depending on the usage.

Non-compliant

Non-compliant example

Compliant example

Compliant example

R1.2 Describe initializations without excess or deficiency.

Preference guide ●

Rule Specification

Preference guide

Rule Specification

29Reliability1● R1_nitialize areas and use them in consid eration of their sizes.

1

Reliability

   

1.3                 

R1.3.1

#define N 10int data[N];int *p;int i;p = data;i = 1;Compliant example of (1) and (2)data[i] = 10; /* OK */data[i+3] = 20; /* OK */Compliant example of (2)*(p + 1) = 10;

#define N 10int data[N];int *p;p = data;Non-compliant example of (1)*(p + 1) = 10; /* Non-compliant */p += 2; /* Non-compliant */Non-compliant example of (2)*(p + 20) = 10; /* Non-compliant */

Performing operations on pointers can make destinations pointed by the pointers to be unclear. It raises the possibility of implanting bugs that is likely to refer or write to unsecured areas. Rather, using an ar-ray name that points to the beginning of the area and to access elements of the array with indices will make the program safer. A dynamic memory area obtained by malloc should be treated as an array, and a pointer to the starting address of the area should be handled as the array name. For the rule (2), it is possible to point to the area directly after the last element of the array as long as the array element is not accessed. For example, in a case where int arr[N] and p=data, p+N complies with the rule as long as it is not used for accessing the array elements. Using like *(p+N) which access an array element is non-compliant.

Compliant example Non-compliant example

R1.3 Pay attention to the range of the area pointed by a pointer

Preference guide ●

Rule Specification Choose

(1) Integer additions or subtractions (including ++, --) on pointers shall not be performed; Array format with [] shall be used for references and assignments to the allocated area.

(2) Integer additions or subtractions (including ++, --) on pointers shall be performed only when the pointer points to an array, and the re-sult must reside within the range of the array.

30 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

Subtractions between pointers shall only be used for those pointing to elements in the same array.

R1.3.2

ptrdiff_t off; /* ptrdiff_t is the type of the result of         pointer subtraction defined in stddef.h */int var1[10];int *p1, *p2;p1 = &var1[5];p2 = &var1[2];off = p1 - p2; /* OK */

ptrdiff_t off; /* ptrdiff_t is the type of the result of         pointer subtraction defined in stddef.h */int var1[10],var2[10];int *p1, *p2;p1 = &var1[5];p2 = &var2[2];

In C language, subtracting between pointers expresses how many elements exist between the two ele-ments pointed to by each of the pointers. In this case, if each pointer points to different arrays, the way the variables laid out between them is compiler dependent and the results are not guaranteed. This shows that subtractions between pointers are meaningful only when the pointers point to elements in the same array. Therefore, when subtractions between pointers are made, the programmer must ensure that both pointers point to the same array.

[Related rule] R1.3.3

Comparisons between pointers shall be applied only to pointers to elements in the same array or mem-bers of the same structure.

R1.3.3

#define N 10char var1[N];void func(int i, int j) { if (&var1[i] < &var1[j]) { …

#define N 10char var1[N];char var2[N];void func(int i, int j) { if (&var1[i] < &var2[j]) { …

Comparing addresses of different variables does not cause a compile error but is meaningless because alignment of the variables depend on the compiler. In addition, the behavior of such a comparison is not defined (undefined behavior).

[Related rules] R1.3.2, R2.7.3

Non-compliant example

Non-compliant example

Compliant example

Compliant example

Preference guide ●

Rule Specification

Preference guide ●

Rule Specification

31

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

Use data in consideration of their ranges, sizes and internal representations.

Reliability

2

Various data handled in programs have different internal representations and different ranges to be operated according to their types. If such various data are used for operations such as calculations, an unexpected malfunction may occur unless careful attention to data preci-sion or size etc. is paid when using the data. Therefore, when handling data, be aware of their ranges, sizes and internal representations.

Reliability 2.1 Make comparisons that do not depend on internal representations.

Reliability 2.2 Do not examine whether a value is equivalent to true value.

Reliability 2.3 Use the same data type to perform operations or make comparisons.

Reliability 2.4 Describe code in consideration of operation precision.

Reliability 2.5 Do not use operations that have a risk of information loss.

Reliability 2.6 Use types with which the target data can be represented.

Reliability 2.7 Pay attention to pointer types.

Reliability 2.8 Write in the way that the compiler can check if there is

no contradiction in declarations, usages and definitions.

32 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

   

2.1 Make comparisons that do not depend on internal representations.

Equality or inequality comparisons shall not be made for floating-point expressions.

R2.1.1

#define LIMIT 1.0e-4void func(double d1, double d2) { double diff = d1 - d2; if (-LIMIT <= diff && diff <= LIMIT) { …

void func(double d1, double d2) { if (d1 == d2) { …

For a floating-point type, values written in source code are not exactly equivalent to those actually im-plemented, therefore, the comparisons should be made in consideration of the tolerance.

[Related rule] R2.1.2

Floating-point variables shall not be used as loop counters.

R2.1.2

void func() { int i; for (i = 0; i < 10; i++) {  …

void func() { double d; for (d = 0.0; d < 1.0; d += 0.1) {  …

If operations are repeatedly carried out to a loop counter of a floating-point type, the intended result may not be achieved due to the accumulated calculation errors. Thus, integer type (int type) should be used for loop counters.

[Related rule] R2.1.1

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R2.1Make comparisons that do not depend on internal representations.

Preference guide ●

Rule Specification

Preference guide ●

Rule Specification

33

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

memcmp shall not be used to compare structures and unions.

R2.1.3

struct { char c; long l; } var1, var2;void func() { if (var1.a == var2.a && var1.b == var2.b) { …

struct { char c; long l; } var1, var2;void func() { if (memcmp(&var1, &var2, sizeof(var1)) == 0) {…

Memories for structures and unions may contain unused areas. Since the values in the areas are un-known, memcmp should not be used. When making comparisons of structures or unions, they should be made between the corresponding members.

[Related rule] M1.6.2

Do not examine whether a value is equivalent to true value

Comparison with a value defined as true shall not be made in expressions that examine true or false.

R2.2.1

#define FALSE 0/* func1 may return a value other than 0 and 1 */void func2() { if (func1() != FALSE) { - or - if (func1()) {

#define TRUE 1/* func1 may return a value other than 0 and 1 */void func2() { if (func1() == TRUE) {

In C language, true is denoted by a nonzero value, not necessarily 1.

[Related rule] M1.5.2

Non-compliant example

Non-compliant exampleCompliant example

Compliant example

R2.2Do not examine whether a value is equivalent to true value.

Preference guide ●

Rule Specification

Preference guide

Rule Specification

34 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

   

2.3 Use the same data type to carry out operations or make comparisons

Unsigned integer constant expressions shall be described within the range that can be represented with the result type.

R2.3.1

#define MAX 0xffffUL /* Specify long type*/unsigned int i = MAX;if (i < MAX + 1)/* If long is 32 bits, there is no problem if the number of bits for int is different.*/

#define MAX 0xffffUunsigned int i = MAX;if (i < MAX + 1)/* The result is different depending on whether int is 16 bits or 32 bits. If int is 16 bits, the operation result wraps around and the comparison result is false. If int is 32 bits, the operation result is within the range of int and the comparison result is true. */

Unsigned integer operations in C language wrap around without overflow (the result is the remainder of the maximum representable value). Thus, there are cases where the operation result is different from the intention without being noticed. For example, the same constant expression will produce different operation results in an environment where the number of bits for int is different, and the results will be different depending on whether they exceed the range representable with the type or not.

For a conditional operator (?: operator), the logical expression shall be put in parenthese and the both return values shall be the same type.

R2.3.2

void func(int i1, int i2, long l1) { i1 = (i1 > 10) ? i2 : (int)l1;

void func(int i1, int i2, long l1) { i1 = (i1 > 10) ? i2 : l1;

When writing code using different types, cast either one to specify which type is expected for the result.

[Related rule] M1.4.1

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R2.3Use the same data type to perform operations or make comparisons

Preference guide

Rule Specification

Preference guide

Rule Specification

35

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

Loop counters and variables used for making com-parisons of loop iteration conditions shall be the same type.

R2.3.3

void func(int arg) { int i; for (i = 0; i < arg; i++) {

void func(int arg) {  unsigned char i; for (i = 0; i < arg; i++) {

Comparisons of variables with different ranges of representable values for loop iteration conditions may produce unintended result and end up with an infinite loop.

   

2.4 Describe code in consideration of operation precision

When the type of an operation and the type of the assignment destination of its result are different, the operation shall be performed after casting them to the type of the expected operation precision.

R2.4.1

int i1, i2;long l;double d;void func() { d = (double)i1 / (double)i2; /* floating-point devision */ l = ((long)i1) << i2; /* Shift using long */

int i1, i2;long l;double d;void func() { d = i1 / i2; /* int type division */ l = i1 << i2; /* Shift using int */

The type of an operation is determined by the type of the expressions (operands) used for the operation, and the type of the assignment destination is not considered. If the types of the operation and the assign-ment destination are different, the program may wrongly expect to operate with the type of the assign-ment destination. If an operation with a different type from those of operands is desired, it is necessary to cast them into the expected type before executing the operation.

[Related rule] R2.5.1

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R2.4 Describe code in consideration of operation precision

Preference guide ●

Rule Specification

Preference guide ●

Rule Specification

36 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

When making arithmetic operations or comparisons mixed with signed and unsigned expressions, ex-plicit casting shall be made into the expected type.

R2.4.2

long l;unsigned int ui;void func() { l = l / (long)ui; - or - l = (unsigned int)l / ui;

if (l < (long)ui) {- or - if ((unsigned int)l < ui) {

long l;unsigned int ui;void func() { l = l / ui; if (l < ui) { …

Some operations such as size comparison, multiplications and divisions have different results depending on whether they are carried out with signed or unsigned. If an operation is written by mixing signed and unsigned, unsigned operation is not always made because which one to use is determined in consider-ation of each of data sizes. Therefore, if mixed arithmetic operations are performed, it is necessary to check whether the expected operation is signed or unsigned and explicitly cast to the type to achieve the expected operation. Note: In many cases, it is better to change data types used rather than casting mechanically. Changing data types should be considered first.

Non-compliant exampleCompliant example

Preference guide

Rule Specification

37

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

   

2.5 Do not use operations that have a risk of information loss.

R2.5.1

/* Assignment examples */short s; /* 16 bits */long l; /* 32 bits */void func() { s = (short)l; s = (short)(s + 1);}/* Operation examples */unsigned int var1, var2; /* int size is 16 bits */ var1 = 0x8000; var2 = 0x8000; if ((long)var1 + var2 > 0xffff) { /* The result is true */

/* Assignment examples */short s; /* 16 bits */long l; /* 32 bits */void func() { s = l; s = s + 1;}/* Operation examples */unsigned int var1, var2; /* int size is 16 bits */var1 = 0x8000;var2 = 0x8000;if (var1 + var2 > 0xffff) { /* The result is false */

Assigning a value to a variable with a different type may change its value (loose information). If pos-sible, the assignment destination should be the same type. If a value is assigned to a different type inten-tionally, in cases such as no risk of information loss or allowance of information loss, describe casts to clearly indicate the intention. For operations, if an operation result exceeds the range of representable value with its type, it may result in an unexpected value. To be secure, verify that the operation result is within the range of represent-able value with its type and then carry out the operation. Alternatively, convert the type into one that can handle larger values and then carry out the operation.

Note: In many cases, it is better to change data types used rather than casting mechanically. Changing data types should be considered first.

[Related rule] R2.4.1

Compliant example Non-compliant example

R2.5Do not use operations that have a risk of information loss.

Preference guide ○

Rule Specification

When performing assignments (=operation, actual arguments passing of function calls, function re-turn) or operations to data types that may cause information loss, check that there are not any problems. Casts shall be described to clearly indicate that there are no problems.

38 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

Unary operator ('-') shall not be used in unsigned expressions.

R2.5.2

int i;void func() { i = -i;

unsigned int ui;void func() { ui = -ui;

If unary operators ('-') are used in unsigned expressions and the operation result becomes outside the range of representable value with the original unsigned type, unexpected behavior may occur. For example, if “if (-ui<0)” is written in the above example, this “if” will not be true.

When one’s complement (~) or left shift (<<) is ap-plied to data with unsigned char type or unsigned short type, they shall be explicitly casted to the type of the result.

R2.5.3

uc = 0x0f;if((unsigned char)(~uc) >= 0x0f)

uc = 0x0f;if((~uc) >= 0x0f) /* It is not true */

The operation result of unsigned char or unsigned short is signed int. If the sign bit becomes on by the operation, the expected result may not be achieved. Thus, clearly indicate the casts to the type of the expected operation. The non-compliant example shows that ~us always becomes false as it pro-duces a negative value.

[Related rule] R2.5.4

Non-compliant example

Non-compliant example

Compliant example

Compliant example

Preference guide ●

Rule Specification

Preference guide ○

Rule Specification

39

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

The right-hand side of a shift operator shall be zero or more and less than the bit width of the left-hand side.

R2.5.4

unsigned char a; /* 8 bits */unsigned short b; /* 16 bits */b = (unsigned short)a << 12; /* Clearly indicated that the operation is 16 bits */

unsigned char a; /* 8 bits */unsigned short b; /* 16 bits */b = a << 12; /* There may be an error in the shift count */

The behavior of a shift operator in cases where its right-hand side (the shift count) specifies a negative value or a value not smaller than the bit width (the bit width of int if the size is smaller than int) of the left-hand side (shifted value) is not defined in C language standard and is different depending on compilers. Specifying a value of shift count up to the bit width of int when the left-hand side (shifted value) is a type of smaller size than int makes the intention unclear although the behavior is defined by the lan-guage standard.

[Related rule] R2.5.3

Non-compliant exampleCompliant example

Preference guide ●

Rule Specification

40 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

   

2.6 Use types with which the target data can be reprenseted.

The types used for bit field shall only be signed int and unsigned int. If a bit field of 1 bit width is required, not the signed int type but the unsigned int type shall be used.

R2.6.1

struct S { signed int m1:2; unsigned int m2:1; unsigned int m3:4;};

struct S { int m1:2; /* Sign is not specified */ signed int m2:1; /* Signed and 1bit */ char m3:4; /* Type other than int */};

When int without sign specification is used for a bit-field, it depends on compilers whether signed or un-signed int is used for it. Therefore, int type without sign specification should not be used for bit-fields. In addition, char, short or long type for bit-fields should not be used when portability is considered, because their use is outside C language standard, even if a compiler supports it. Since values that can be repre-sented by a bit-field of 1 bit signed int are only -1 and 0, an unsigned int should be used for a bit-field of 1 bit.

[Related rule] P1.3.3

Data used as bit sequences shall be defined with unsigned type, not signed.

R2.6.2

unsigned int flags;void set_x_on() { flags |= 0x01;

signed int flags;void set_x_on() { flags |= 0x01;

Results of bitwise operations (-, <<, >>, &, ^, |) to signed type may be different depending on compilers.

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R2.6Use types with which the target data can be rep-renseted.

Preference guide ○

Rule Specification

Preference guide

Rule Specification

41

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

   

2.7 Pay attention to pointer types.

(1) Pointer types shall not be converted to other pointer types or integer types, the opposite con-versions shall not be perfprmed either. However, conversion between the void* type and pointer types to data is the exception.

R2.7.1

int *ip;int (*fp)(void) ;char *cp;int i;void *vp;

Compliant example of (1)ip = (int*)vp;

Compliant example of (2)i = (int)ip;

Compliant example of (3)i = (int)fp;cp = (char*)ip;

int *ip;int (*fp)(void) ;char c;char *cp;

Non-compliant example of (1)ip = (int*)cp;

Non-compliant example of (2)c =(char) ip;

Non-compliant example of (2)ip =(int*) fp;

If a pointer type variable is casted or assigned to another pointer type, it is difficult to identify what kind of data is contained in the area the pointer points to. With some MPUs, runtime errors occur if the des-tination of a pointer that is not at word boundaries is accessed as int type; thus changing pointer types may cause a risk of unexpected bugs. It is safer not to cast or assign pointer type variables to other point-er types. Converting pointer types to integral types may also cause a similar risk as the problem stated above and reviews with experts should be carried out, if necessary. In addition, be aware of the value ranges of the int type and the pointer type. Be sure to check the compiler specification beforehand as it may be the case that the size of the pointer type is 64 bits even though that of the int type is 32 bits.

Non-compliant exampleCompliant example

(2) Pointer types shall not be converted to other pointer types or int types with less data width than that of the pointer type. However, conversion between the void* type and pointer types to data is the exception.

(3) Pointer types to data can be converted to pointer types to other data types, but pointers to function types shall not be converted to those to other function types or data types. When a pointer type is converted to an integral type, conversion to an integral type with less data width than that of the pointer type shall not be performed.

R2.7 Pay attention to pointer types.

Preference guide ○

Rule Specification Choose

42 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

A cast shall not be performed that removes any const or volatile qualification from the type ad-dressed by a pointer.【MISRA 11.5】

R2.7.2

void func(const char *);const char *str;void x() { func(str); …}

void func(char *);const char *str;void x() { func((char*)str); …}

Since areas qualified by const or volatile can be only for reference or should not be optimized, be careful when accessing the areas. If a cast to remove const or volatile is applied for pointers to these areas, the above caution becomes overlooked and the compiler will not be able to make any check for such errors in the program.

Comparison that examines whether a pointer is negative or not shall not be made.

R2.7.3

— int * func1() { … return -1;}int func2() { … if (func1() < 0) { /* Intend to check if         negative or not */  … } return 0;}

It should be noted that comparison of a pointer with 0 is meaningless. If it is compared with a pointer, 0 is converted to the null pointer by the compiler. Therefore, the com-parison is actually between pointers and may not result in the expected behavior.

[Related rule] R1.3.3

Non-compliant example

Non-compliant example

Compliant example

Compliant example

Preference guide ○

Rule Specification

Preference guide ●

Rule Specification

43

1

Reliability

Reliability2● R2_Use data in consideration of ranges,sizes and internal representations.

2

Reliability

   

2.8 Write in the way that compiler can check if there is no contradiction in declarations, usages and definitions.

Functions with no parameters shall be declared with a void type parameter.

R2.8.1

int func(void) ; int func();

The declaration int func() does not mean a function with no parameters, but a function with un-known number and types of parameters, which is an old-style (K&R style.) Write explicitly void when declaring functions with no parameters.

[Related rule] R2.8.3

(1) Functions shall not be defined with a variable number of arguments. [MISRA 16.1]

(2) When using functions with a variable number of arguments, <<document their behavior in the processing system>>.

R2.8.2

Compliant example of (1)int func(int a, char b);

Non-compliant example of (1) int func(int a, char b, ... );

Without understanding the behavior of functions with a variable number of arguments in the processing system, their use may cause an unexpected result. In addition, when the number of arguments is variable, the number and the types of the arguments are not explicitly specified, and it will lower readability of the code.

[Related rule] R2.8.3

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R2.8Write in the way that the compiler can check if there is no contradiction in declarations, usages and definitions.

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification

ChooseDocument

44 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

2

Reliability

A prototype declaration shall be made before func-tion calls and its function definition. In addition, make sure that the same prototype declaration is referenced by their calls and its definition.

R2.8.3

-- file1.h --void f(int i);

-- file1.c --#include "file1.h"void f(int i) { … }

-- file2.c --#include "file1.h"void g(void) { f(10); }

-- file1.c --void f(int i); /* Declared in each file */void f(int i) { … }

-- file2.c --void f(int i); /* Declared in each file */void g(void) { f(10); }

For function declarations, there are the K&R style and the function prototype style. With the K&R style, the compiler cannot check the types of the arguments in a function, it is difficult to find programmer’s mistakes. Therefore, use the function prototype declaration. Avoid using both the function prototype and K&R styles mixed for definition and declaration of one function, or it may cause an unexpected prob-lem.

[Related rules] R2.8.1, R2.8.2

Non-compliant exampleCompliant example

Preference guide ○

Rule Specification

45

1

Reliability

Reliability3● R3_Write in a way to ensure behavior.

3

Reliability

Write in a way to ensure the behavior.Reliability

3

It is necessary to thoroughly describe how to handle errors for cases impossible to occur under the program specification, in consideration of happening of unexpected events. In addition, the way of coding that does not rely on the language specifications such as explicit indication of operator precedence can improve safety. To realize high reliability, it is desirable to avoid coding that leads to malfunction and write in a way to ensure the behavior and safety as much as possible.

Reliability 3.1 Write code in consideration of sizes of areas.

Reliability 3.2 Avoid error cases for operations that may cause

runtime errors.

Reliability 3.3 Check the interface restrictions for function calls.

Reliability 3.4 Do not apply recursive calls.

Reliability 3.5 Pay attention to branch conditions and describe

handling processes in case those not stated occur. 

Reliability 3.6 Pay attention to the evaluation order.

46 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

3

Reliability

   

3.1 Write code in consideration of sizes of areas

R3.1.1

Compliant example of (1)extern char *mes[3];…char *mes[] = {"abc", "def", NULL};

Compliant example of (2) extern char *mes[];…char *mes[] = {"abc", "def", NULL};

Compliant example of (1) and (2)extern int var1[MAX];…int var1[MAX];

Non-compliant example of (1)extern char *mes[];…char *mes[] = {"abc", "def", NULL};

Non-compliant example of (1) and (2)extern int var1[];…int var1[MAX];

Making an extern declaration without specifying the size of an array will not cause an error. However, if the size is not specified, it may cause problems for checking the array range. Therefore, it is better to explicitly specify the array size in its declaration. However, there are cases where it is better not to specify the array size in the declaration such as cases where the size of the array is determined by the number of initial values and is not fixed in the declaration.

[Related rule] R3.1.2

Non-compliant exampleCompliant example

R3.1 Write code in consideration of sizes of areas

Preference guide ○

Rule Specification Choose

(1) The number of elements in an extern declara-tion of an array shall be specified.

(2) The number of elements in an extern declara-tion of an array shall be specified except for that corresponding to an array definition with initialization that does not specify the number of elements.

47

1

Reliability

Reliability3● R3_Write in a way to ensure behavior.

3

Reliability

Iteration conditions for a loop to sequentially ac-cess array elements shall include a decision wheth-er the access is within the range of the array.

R3.1.2

char var1[MAX];for (i = 0; i < MAX && var1[i] != 0; i++) { /* Even if 0s are not set in the var1 array, there is no risk of accessing outside the array range */ …

char var1[MAX];for (i = 0; var1[i] != 0; i++) { /* If 0s are not set in the var1 array, there is a risk of accessing outside the array range */ …

This rule is to prevent accessing outside the range.

[Related rule] R3.1.1

   

3.2 Avoid error cases for operations that may cause runtime errors.

Operations shall be performed after checking that the right-hand side expression of division or remainder is not 0.

R3.2.1

if (y != 0) ans = x/y;

ans = x/y;

Apart from when the value is obviously not 0, the operations should be performed after checking that the right-hand side expression of division or remainder is not 0. Otherwise, division by zero error may occur at runtime.

[Related rules] R3.2.2, R3.3.1

Non-compliant exampleCompliant example

Preference guide

Rule Specification

Non-compliant exampleCompliant example

R3.2Avoid error cases for operations that may cause run-time errors.

Preference guide

Rule Specification

48 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

3

Reliability

Destination pointed by a pointer shall be referred to after checking that the pointer is not the null pointer.

R3.2.2

if (p != NULL) *p = 1;

*p = 1;

[Related rules] R3.2.1, R3.3.1

   

3.3 Check the interface restrictions for function calls.

If a function returns error information, then that er-ror information shall be tested. 【MISRA 16.10】

R3.3.1

p = malloc(BUFFERSIZE);if (p == NULL) /* Error handling */else *p = '\0';

p = malloc(BUFFERSIZE);*p = '\0';

[Related rules] R3.2.1, R3.2.2, R3.5.1, R3.5.2

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R3.3 Check the interface restrictions for function calls.

Preference guide

Rule Specification

Preference guide

Rule Specification

49

1

Reliability

Reliability3● R3_Write in a way to ensure behavior.

3

Reliability

If there are constraints on parameters passed to a function, the function call shall be performed after checking the parameters are not beyond the limited values.

R3.3.2

if ((MIN <= para) && (para <= MAX)) ret = func(para);

ret = func(para);

   

3.4 Do not apply recursive calls.

Functions shall not call themselves, either directly or indirectly. 【MISRA 16.2】

R3.4.1

— unsigned int calc(unsigned int n){ if (n <= 1) { return 1; } return n * calc(n-1);}

Since the stack size used at runtime for recursive calls cannot be predicted, there is a risk of stack over-flow.

Non-compliant example

Non-compliant example

Compliant example

Compliant example

R3.4 Do not apply recursive calls.

Preference guide

Rule Specification

Preference guide

Rule Specification

50 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

3

Reliability

   

3.5 Pay attention to branch conditions and describe handling processes in cases those not stated occur.

《Put an else clause at the end of an if-else if statement. If it is sure that the else condition does not normally occur, apply either one of the follow-ings.

R3.5.1

/* else clause of an if-else if statement where the else condition does not normally occur */if (var1 == 0) { …} else if (0 < var1) { …} else { /* Write an exception handling process */ …}…if (var1 == 0) { …} else if (0 < var1) { …} else { /* NOT REACHED */

/* if-else if statement without the else clause */if (var1 == 0) { …} else if (0 < var1) { …}

If there is no else clause in an if-else if statement, it is not clear whether the programmer has forgotten to write the else clause or the else clause never occurs. Even if it is known that the else condition does not normally occur, the behavior of the program under unexpected conditions can be pre-dicted by writing the else clause as follows. - Write the behavior under unexpected conditions in the else condition (How program behaves in case

of occurrence of the else condition should be determined.) The program is much easier to understand by just writing a comment that the else condition does not occur. - Write a comment specified by the project such as /* NOT REACHED */ clearly indicating that the else condition does not occur to express that the else clause has not been forgotten.

[Related rules] R3.3.1, R3.5.2

Non-compliant exampleCompliant example

(i) An exception handling process shall be written in the else clause. (ii) A comment specified by the project shall be written in the else

clause. 》

R3.5Pay attention to branch conditions and describe han-dling processes in cases those not stated occur.

Preference guide ○

Rule Specification Define

51

1

Reliability

Reliability3● R3_Write in a way to ensure behavior.

3

Reliability

《Write the default clause at the end of a switch statement. If it is sure that the default condition does not normally occur, apply either one of the fol-lowings.

R3.5.2

/* Default clause in a switch statement where the default condition does not normally occur */switch(var1) {case 0: … break;case 1: … break;default: /* Write an exception handling process */ … break;}…switch(var1) {case 0: … break;case 1: … break;default: /* NOT REACHED */ break;}

/* Switch statement without the default clause */switch(var1) {case 0: … break;case 1: … break;}

If there is no default clause in a switch statement, it is not clear whether the programmer has forgotten to write the default clause or the default clause never occurs. Even if it is known that the default clause does not normally occur, the behavior of the program under unexpected conditions can be pre-dicted by writing the default clause as follows. - Write the behavior under unexpected conditions in the default condition (How program behaves in

case of occurrence of the default condition should be determined.) Or, the program is much easier to understand by just writing a comment that the default condition does not occur. - Write a comment specified by the project such as /* NOT REACHED */ clearly indicating that the

default condition does not occur to express that the default clause has not been forgotten.

[Related rules] R3.3.1, R3.5.1, M3.1.4

Non-compliant exampleCompliant example

(i) An exception handling process shall be written in the default clause. (ii) A comment specified by the project shall be written in the default

clause.》

Preference guide ○

Rule Specification Define

52 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

3

Reliability

Equality or inequality operators shall not be used for comparisons of loop counters. (<=, >=, <, or > shall be used.)

R3.5.3

void func() { int i; for (i = 0; i < 9; i += 2) { …

void func() { int i; for (i = 0; i != 9; i += 2) { …

If the amount of change for the loop counter is not 1, an infinite loop may occur. Therefore, equality or inequality operators should not be used for comparisons to determine the number of loop iterations.

Non-compliant exampleCompliant example

Preference guide

Rule Specification

53

1

Reliability

Reliability3● R3_Write in a way to ensure behavior.

3

Reliability

   

3.6 Pay attention to the evaluation order.

Variables whose values are changed in an expres-sion shall not be referred to or modified in the same expression.

R3.6.1

f (x, x);x++;- or -f (x + 1, x);x++;

f (x, x++);

Compilers do not guarantee the execution (evaluation) order of each actual argument for functions with multiple parameters. The arguments may be executed from the right or from the left. In addition, com-pilers do not guarantee the execution order of the left-hand and the right-hand side of binary operations such as + operation. Therefore, if the same object is updated and referred to in a sequence of arguments or binary operation expressions, the execution result is not guaranteed. Such a problem, where the ex-ecution result is not guaranteed, is called a side effect problem. Code that cause a side effect problem should not be described. In this rule, descriptions such as below which do not cause a side effect problem are not prohibited.x = x + 1;x = f(x);

[Related rules] R3.6.2, M1.8.1

Non-compliant exampleCompliant example

R3.6 Pay attention to the evaluation order.

Preference guide ●

Rule Specification

54 Part2_Coding Practices for Embedded Software:Practices Chart

1

Reliability

3

Reliability

Function calls with side effects and volatile vari-ables shall not be described more than once in a sequence of actual arguments or binary operation expressions.

R3.6.2

1.extern int G_a;x = func1();x += func2();…int func1(void) { G_a += 10; …}int func2(void) { G_a -= 10; …}

2.volatile int v;y = v;f(y, v);

1.extern int G_a;x = func1() + func2(); /* There may cause a side effect problem */…int func1(void) { G_a += 10; …}int func2(void) { G_a -= 10; …}

2.volatile int v;f(v, v);

Compilers do not guarantee the execution (evaluation) order of each actual argument for functions with multiple parameters. The arguments may be executed from the right or flom the left. In addition, com-pilers do not guarantee the execution order of the left-hand and the right-hand side of binary operations such as + operation. Therefore, the execution results of two or more function calls with side effects and volatile variables in a sequence of arguments or binary operation expressions may not be guaranteed. This type of unsafe description should be avoided.

[Related rules] R3.6.1, M1.8.1

Non-compliant exampleCompliant example

Preference guide ○

Rule Specification

Many embedded software developments require mainte-nance tasks such as modifications for the already devel-oped software. There are various reasons for maintenances, examples are as follows.

・When a bug that requires modification is found in parts of the released software.

・When a new function is added to existing software in re-sponse to requests etc. from market toward the product.

When further tasks are added to the already developed soft-ware, the important characteristic is whether the tasks are performed as accurately and efficiently as possible. This is called “maintainability” in the field of system devel-opment. This section clarifies practices to keep and improve the maintainability for embedded software source code.

●Maintainability 1: Consider that others will read the program.

●Maintainability 2: Write in a way so as not to cause modification errors.

●Maintainability 3: Write programs in a simple way.●Maintainability 4: Write in a consistent way.●Maintainability 5: Write in a way easy to test.

Maintainability

56 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

Consider that others will read the program.

It is often the case that source code is reused and maintained by engineers other than the original creators. Therefore, it is necessary to write source code in a way easy to understand in consideration that others will read it in the future.

Maintaiability 1.1 Do not leave unused descriptions.

Maintaiability 1.2 Do not write in a misleading way.

Maintaiability 1.3 Do not write in a specialized way.

Maintaiability 1.4 Write in a way that operator precedence is explicitly specified.

Maintaiability 1.5 Do not omit operations that obtain function address-es or comparison operations.  

Maintaiability 1.6 Use one area for one purpose.

Maintaiability 1.7 Do not reuse names.

Maintaiability 1.8 Do not use language specifications that can cause misunderstanding.

Maintaiability 1.9 Explicitly state the intention for a specialized way of

writing. 

Maintaiability 1.10 Do not embed magic numbers.

Maintaiability 1.11 Explicitly state the attributes of areas.

Maintaiability 1.12 Correctly describe statements even they are not compiled.

Maintainability

1

57Maintainability1●M1_Consider that others will read the program.

1

Maintainability

Unused functions, variables, arguments or labels shall not be declared (defined.)

M1.1.1

void func(void) { void func(int arg) {  /* arg is not used */

Declarations (definitions) of unused functions, variables, arguments or labels impairs maintainability as it is difficult to determine whether the programmer has forgotten to delete them or has made a descrip-tion error.

[Related rules] M1.9.1, M4.7.2

Sections of code should not be “commented out.”【MISRA 2.4】

M1.1.2

…#if 0 /* Ineffective due to ~ */ a++;#endif…

…/* a++; */…

Leaving a part of the code with no effect should be avoided as it makes the code difficult to read. However, when it is necessary to make parts of the code ineffective, instead of commenting them out, a rule to explicitly indicate the ineffective code parts should be defined, such as by enclosing them with #if 0.

[Related rules] M1.12.1, M4.7.2

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification

M1.1 Do not leave unused descriptions.

58 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

保保保

1.2 保保保保保保保保保保保保保

M1.2.1

Compliant example of (1)int i;int j;Compliant example of (2)int i, j;int k = 0;

int *p;int i;

Non-compliant example of (1)int i, j;Non-compliant example of (2) int i, j, k = 0; /* A variable with   initialization and variables without   initialization are mixed (Non-compliant) */

int *p, i; /* Variables of different types  are mixed (Non-compliant) */

If the declaration is int *p;, the type of p is int*. However, if the declaration is int *p, q;, the type of q becomes int instead of int*.

[Related rule] M1.6.1

Suffixes shall be added to constant descriptions that can use them to indicate appropriate types. Only an uppercase letter “L” shall be used for a suffix indi-cating a long type integer constant.

M1.2.2

void func(long int);…float f;long int l;unsigned int ui;

f = f + 1.0F; /* Explicitly state that it is a float operation */func(1L); /* Description of L should be an uppercase letter */if (ui < 0x8000U) { /* Explicitly state that it is an unsigned comparison */

void func(long int);…

float f;long int l;unsigned int ui;

f = f + 1.0;func(1l); /* 1l can be confused with 11 */if (ui < 0x8000) { …

M1.2 Do not write in a misleading way.

Compliant example Non-compliant example

Compliant example Non-compliant example

the similar purposes may be declared in one declaration   statement, but variables with initialization and variables   without initialization shall not be mixed.

(1) Only one variable shall be declared in one declaration statement (avoid multiple declara tions.)

(2)Automatic variables of the same type used for

Preference guide

Rule Specification Choose

Preference guide

Rule Specification

59Maintainability1●M1_Consider that others will read the program.

1

Maintainability

Basically, when there is no suffix, an integer constant will be an int type and a floating constant will be a double type. However, when an integer constant value that cannot be expressed with an int type is described, its type will be the one that can express that value. Therefore, 0x8000 will be unsigned int if int is 16 bits, and signed int if int is 32 bits. If you would like to use it as unsigned, it is neces-sary to explicitly describe “U” as the suffix. In addition, in case of a target system where the operation speed differs between floating point number of float type and that of double type, when performing operations between a float type variable and a floating constant without a suffix “F,” constant, it should be noted that the operation will be a double type. For floating constants, writing at least one digit on both sides of the decimal point etc. is a tip to easily recognize that they are floating constants.

[Related rule] M1.8.5

When expressing a long string literal, successive string literals shall be concatenated without using newlines within the string literal.

M1.2.3

char abc[] = "aaaaaaaa¥n" "bbbbbbbb¥n" "ccccccc¥n";

char abc[] = "aaaaaaaa¥n¥ bbbbbbbb¥n¥ ccccccc¥n";

For expressing a long string of multiple lines, it is easier to read a concatenation of multiple string liter-als.

Compliant example Non-compliant example

Preference guide

Rule Specification

60 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

保保保

1.3 保保保保保保保保保保保

Expressions to examine true or false result shall not be described in switch (expression).

M1.3.1

if (i_var1 == 0) { i_var2 = 0;} else { i_var2 = 1;}

switch (i_var1 == 0) {case 0: i_var2 = 1; break;default: i_var2 = 0; break;}

When an expression to examine true or false result is used in a switch statement, the number of the branch directions will be two, and the necessity of using the switch statement as a multiple branching command becomes low. Compared to if statements, switch statements have a higher possibility of er-rors, such as writing the default clause wrongly or missing break statements. Therefore, it is recom-mended to use if statements unless the number of the branch directions is three or more.

The case labels and the default label in a switch statement shall be described only in the compound statement (excluding nested compound statements) of the switch statement body.

M1.3.2

switch (x) {case 1:  { …  }  …  break;case 2:  …  break;default: … break;}

switch (x) { /* Compound statement of the          switch statement body */case 1:  { /* Nested compound statement */case 2: /* The case label should not be in a       nested compound statement */ …  }  …  break;default: … break;}

M1.3 Do not write in a specialized way.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ●

Rule Specification

Preference guide

Rule Specification

61Maintainability1●M1_Consider that others will read the program.

1

Maintainability

The types shall be explicitly described for definitions and declarations of functions and variables.

M1.3.3

extern int global;

int func(void) { …}

extern global;

func(void) { …}

If data types are not described in definitions and declarations of functions or variables, they are inter-preted as int type. Explicitly specifying data types improves readability.

[Related rule] M4.5.1

保保保

1.4 保保保保保保保保保保保保保保保保保保保保保保

The right-hand side and the left-hand side of && and || operations shall be described with simple vari-ables or expressions enclosed by (). However, if && operations are successively combined or || opera-tions are successively combined, it is not necessary to enclose each && and || expression with ().

M1.4.1

if ((x > 0) && (x < 10))if ((!x) || y)if ((flag_tb[i]) && status)if ((x != 1) && (x != 4) && (x != 10))

if (x > 0 && x < 10)if (! x || y)if (flag_tb[i] && status)if (x != 1 && x != 4 && x != 10)

Variables, constant expressions, string literals and expressions enclosed by () are called primary ex-pressions. This rule states that each operand of && or || should be a primary expression. The aim is to highlight the operation of each operand in && or || operations to improve readability by enclosing an expression that contains an operator with ().

[Related rules] R2.3.2 M1.5.2

M1.4 Write in a way that operator precedence is explic-itly specified.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ●

Rule Specification

Preference guide

Rule Specification

62 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

《Usage of parentheses to explicitly indicate operator precedence shall be specified.》

M1.4.2

a = (b << 1) + c; - or -a = b << (1 + c);

a = b << 1 + c; /* There is a possibility that the operator precedence is misunderstood */

The order of operators in C language tends to be misunderstood so it is better to make rules such as be-low, for example. If an expression contains multiple binary operators with different precedence, paren-theses should be used to clarify their precedence. However, for the four arithmetic operations, parenthe-ses can be omitted.

[Related rule] M1.5.1

保保保

1.5 保保保保保保保保保保保保保保保保保保保保保保保保

A function identifier (function name) shall only be used with either a preceding “&”, or with a parenthe-sized parameter list, which may be empty.

【MISRA 16.9】

M1.5.1

void func(void);void (*fp)(void) = &func;

if (func()) {

void func(void);void (*fp)(void) = func; /* No-compliant: There is no & */if (func) { /* No-compliant: Address is obtained rather than calling the function. It might be mistakenly written as a function call without arguments. */

In C language, if a function name is described by itself, it will not call the function but obtain the func-tion address. This means that it is not necessary to place & for getting the function address. However, if & is not placed, it might be misunderstood that it is a function call (for example, when using languages such as Ada that describe a subprogram call without argument by writing its name alone). By following the rule to add & when obtaining the function address, checking for occurrences of function names with-out & and not followed by () is done and mistakes (errors) can be found out.

[Related rule] M1.4.2

M1.5 Do not omit operations that obtain function ad-dresses or comparison operations.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification Define

Preference guide

Rule Specification

63Maintainability1●M1_Consider that others will read the program.

1

Maintainability

Comparisons with 0 shall be explicitly written.M1.5.2

int x = 5;

if (x != 0) { …}

int x = 5;

if (x) { …}

In conditional expressions, the expression result 0 is judged as false and nonzero as true. Therefore, !=0 may be omitted in conditional expressions. However, it is better not to omit it to make the program’s in-tention clear.

[Related rules] R2.2.1 M1.4.1

保保保

1.6 保保保1保保保保保保保保保保保保

Variables shall be prepared for each purpose.M1.6.1

/* Counter variable and work variable for replacement are different */for (i = 0; i < MAX; i++) { data[i] = i;}if (min > max) { wk = max; max = min; min = wk;

/* Counter variable and work variable for replacement are the same */for (i = 0; i < MAX; i++) { data[i] = i;}if (min > max) { i = max; max = min; min = i;

Reusing variables should be avoided as it impairs readability and increases the risk of not being fixed correctly during modification.

[Related rule] M1.2.1

M1.6 Use one area for one purpose.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification

Preference guide

Rule Specification

64 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

(1) Unions shall not be used. 【MISRA 18.4】 (2) If unions are used, the same members that are assigned values shall be referenced.

M1.6.2

compliant example of (2)/* type is INT→i_var, CHAR→c_var[4] */struct stag { int type; union utag { char c_var[4]; int i_var; } u_var;} s_var;…int i;…if (s_var.type == INT) { s_var.u_var.i_var = 1;}…i = s_var.u_var.i_var;

Non-compliant example of (2)/* type is INT→i_var, CHAR→c_var[4] */struct stag { int type; union utag { char c_var[4]; int i_var; } u_var;} s_var;…int i;…if (s_var.type == INT) { s_var.u_var.c_var[0] = 0; s_var.u_var.c_var[1] = 0; s_var.u_var.c_var[2] = 0; s_var.u_var.c_var[3] = 1;}…i = s_var.u_var.i_var;

One memory space with different sizes of types can be declared as a union. However, the way bits of data are overlapped among the members depends on the processing systems, so an unexpected behavior may be caused. If unions are used, a caution like rule (2) should be required.

[Related rule] R2.1.3

Compliant example Non-compliant example

Preference guide

Rule Specification Choose

65Maintainability1●M1_Consider that others will read the program.

1

Maintainability

保保保

1.7 保保保保保保保保保保

M1.7.1

int var1;void func(int arg1) { int var2; var2 = arg1; { int var3; var3 = var2; … }}

int var1;void func(int arg1) { int var1; /* The same name of a variable outside the function is used */ var1 = arg1; { int var1; /* The same name of a variable in the outer scope is used */   … var1 = 0; /* Intention of which var1 is assigned is unclear */ … }}

Using unique names within a program as much as possible, except for those with limited scope such as automatic variables, makes the program easier to read. In C language, in addition to scopes by file and block, names have the following four namespaces ac-cording to categories they belong to. 1. labels  2. tags  3. members of structures and unions  4. other identifiers *macros have no namespace The language specification allows using the same name to different identifiers if their namespaces are different, but this rule restricts the usage in order to improve the readability of the program.

[Related rule] M4.3.1

M1.7 Do not reuse names.

1. Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier. 【MISRA 5.2】

2. A typedef name shall be a unique identifier. 【MISRA 5.3】3. A tag name shall be a unique identifier.【MISRA 5.4】4. No object or function identifier with static storage duration should be reused. 【MISRA 5.5】5. No identifier in one namespace should have the same spelling as an identifier in another namespace, with the exception of structure member and union member names.【MISRA 5.6】

Compliant example Non-compliant example

The rules below shall be followed for name unique-ness.

Preference guide ○

Rule Specification Choose

66 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

Names for functions, variables and macros in the standard library shall not be redefined or reused. In addition, those macro names shall not be undefined.

M1.7.2

#include <string.h>void *my_memcpy(void *arg1, const void *arg2, size_t size) { …}

#undef NULL#define NULL ((void *)0)

#include <string.h>void *memcpy(void *arg1, const void *arg2, size_t size) { …}

Redefining names for functions, variables and macros defined in the standard library degrades the read-ability of the program.

[Related rule] M1.8.2

Names (variables) that start with an underscore shall not be defined.

M1.7.3

— int _Max1; /* Reserved */int __max2; /* Reserved */int _max3; /* Reserved */

struct S { int _mem1; /* Not reserved but not to be used */};

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification

67Maintainability1●M1_Consider that others will read the program.

1

Maintainability

C language standard defines the following names as reserved.(1)Names that start with an underscore and either an uppercase letter or another underscore.  Examples:_Abc, __abc

(2)Names that start with an underscore  These names are reserved for variables or functions with file scope and for tag names.   If the reserved names are redefined, behavior of the compiler is not guaranteed.   Names that start with an underscore followed by lowercase letters are not reserved for outside the   file scope, but to make it easy to remember, this rule defines that all names starting with an under   score should not be used.

[Related rule] M1.8.2

保保保

1.8 保保保保保保保保保保保保保保保保保保

The right-hand operand of a logical && or || operator shall not contain side effects. 【MISRA 12.4】

M1.8.1

a = *p;p++;/* p has been counted up regardless of the content pointed by p*/if ((MIN < a) && (a < MAX)) { …}

/* (hard to understand) Whether p is counted up or not depends on whether the content pointed by p is smaller than MIN or greater than or equal to MIN */if ((MIN < *p) && (*p++ < MAX)) { …}

The right-hand side of && or || operators may not be executed depending on the result of the condition of their left-hand side. If expressions with side effects such as increments are written for the right hand side, it becomes hard to understand whether or not the increment is executed because the condition of the left-hand side determines it. Therefore, expressions with side effects should not be described for the right-hand side of && or || operators.

M1.8Do not use language specifications that can cause misunderstanding.

Compliant example Non-compliant example

Preference guide

Rule Specification

68 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

C macros shall only expand to a braced initializer, a constant, a parenthesised expression, a type quali-fier, a storage class specifier, or a do-while-zero con-struct. 【MISRA 19.4】

M1.8.2

#define START 0x0410#define STOP 0x0401

#define BIGIN {#define END }#define LOOP_STAT for(;;) {#define LOOP_END }

Taking advantages of macro definitions can make the code look like it is written in a language other than C, or greatly reduce the amount of code. However, using macros for these purposes will degrade read-ability. It is important to use macros only where coding and modification errors can be avoided. For do-while-zero, see MISRA-C:2004.

[Related rule] M1.7.2

#line shall not be used unless automatically gener-ated by a tool.

M1.8.3

The function of #line is to intentionally modify file names or line numbers of warning or error mes-sages from the compiler. It is provided under the assumption of code generation by tools, and should not be directly used by programmers.

Compliant example Non-compliant example

Preference guide

Rule Specification

Preference guide

Rule Specification

69Maintainability1●M1_Consider that others will read the program.

1

Maintainability

A sequence of three or more characters starting with ?? shall not be used.

M1.8.4

s = "abc?(x)"; s = "abc??(x)"; /* Compilers enabling trigraph sequence interpret this as “abc[x)” */

C language standard defines trigraph sequences starting with ?? assuming that a situation where char-acters required for coding cannot be used in a development environment. The following nine patterns of three character notations: ??=, ??(, ??/, ??), ??’, ??<, ??!, ??> ,??- are replaced with the correspond-ing single character: #, [, ¥, ], ^, {, |, } , ~, respectively. However, since they are not frequently used, many compilers support this feature by an option.

Octal constants (other than zero) and octal escape sequences shall not be used. 【MISRA 7.1】

M1.8.5

a = 0;b = 8;c = 100;

a = 000;b = 010;c = 100;

Constants starting with 0 are interpreted as octal. 0s cannot be added in front of decimal numbers to align their digits for an appearance purpose.

[Related rule] M1.2.2

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification

Preference guide

Rule Specification

70 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

保保保

1.9 保保保保保保保保保保保保保保保

If statements that do nothing need to be intentionally described, comments or empty macros shall be used to make them noticeable.

M1.9.1

for (;;) { /* Waiting for interruption */}

#define NO_STATEMENTi = COUNT;while ((--i) > 0) { NO_STATEMENT;}

for (;;) {}

i = COUNT;while ((--i) > 0);

[Related rules] M1.1.1

《A way of writing infinite loops shall be defined.》M1.9.2

The way to write infinite loops should be unified with one of the following, for example. - Infinite loops are uniformly written as for(;;). - Infinite loops are uniformly written as while(1). - Use a macro made for an infinite loop.

M1.9Explicitly state the intention for a specialized way of writing.

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification Define

71Maintainability1●M1_Consider that others will read the program.

1

Maintainability

保保保

1.10 保保保保保保保保保保保保保保保保

Meaningful constants shall be defined as macros before their use.

M1.10.1

#define MAXCNT 8if (cnt == MAXCNT) { …

if (cnt == 8) { …

By defining constants as macros, their meaning can be clearly indicated and mistakes can be avoided when modifying a program in which the same constant is used in several places, for one macro needs to be changed. However, for data sizes, the sizeof operator should be used instead of macros.

[Related rule] M2.2.4

保保保

1.11 保保保保保保保保保保保

Read-only areas shall be declared as const. M1.11.1

const volatile int read_only_mem; /* Read-only memory */const int constant_data = 10; /* Read-only data that does not require memory allocation *//* Only reads the contents pointed by arg */void func(const char *arg, int n) { int i; for (i = 0; i < n; i++) { put(*arg++); }}

int read_only_mem; /* Read-only memory */int constant_data = 10; /* Only reads the contents pointed by arg *//* Read-only data that does not require memory allocation */void func(char *arg, int n) { int i; for (i = 0; i < n; i++) { put(*arg++); }}

M1.10 Do not embed magic numbers.

M1.11 Explicitly state the attributes of areas.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification

72 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

Declaring variables as const type that are only referenced and not modified make it clear that they are not modified. In addition, the compiler’s optimization process may make the object code size smaller. Therefore, read-only variables should be const type. Memories that are only referenced in a unit of the program but are modified by other execution units should be declared as a const volatile type so that the compiler can detect the error that the program updates them by mistake. Furthermore, function interfaces can be clearly stated by adding consts to parameters when the memory spaces indicated by the parameters are only referenced in function processing.

[Related rule] R1.1.2

Memory spaces that might be updated by other ex-ecution units shall be declared as volatile.

M1.11.2

volatile int x = 1;while (x == 0) { /* x is not modified within the loop and modified by other execution units*/}

int x = 1;while (x == 0) { /* x is not modified within the loop and modified by other execution units*/}

Memory spaces qualified with volatile prohibit the compiler from doing optimization to them. Op-timization prohibition means to generate executable object code faithfully to descriptions that are logi-cally meaningless. For example, suppose a description x; is in the code. It is logically a meaningless statement that only references to the variable x, so if x is not qualified with volatile, the compiler usually ignores such a statement and does not generate an executable object code for it. If x is qualified with volatile, it only reads the variable x (loads it to a register). The meaning of this description is considered to be an interface to IO registers (memory mapped) that are reset when the memory is read. Embedded software has IO registers to control hardware and appropriately qualifying them with vola-tile should be applied according to the IO registers’ characteristics.

Compliant example Non-compliant example

Preference guide ○

Rule Specification

73Maintainability1●M1_Consider that others will read the program.

1

Maintainability

《Rules for variable declaration and definition to ROMize shall be defined》

M1.11.3

const int x = 100; /* Allocate to ROM */ int x = 100;

Variables qualified with const can be allocated to memory spaces targeted for ROMization. When de-veloping a program that uses ROMization, qualify the read-only variables with const, for example, and specify the name of the section to store them by #pragma etc.

[Related rule] R1.1.2

保保保

1.12 保保保保保保保保保保保保保保保保保保保保保

Correct code shall be described even if it is to be de-leted by the preprocessor.

M1.12.1

#if 0 /* */#endif

#if 0…#else int var;#endif

#if 0 /* I don't know */#endif

#if 0 /*#endif

#if 0…#else1 int var;#endif

#if 0 I don't know#endif

[Related rule] M1.1.2

M1.12Correctly describe statements even they are not compiled.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification Define

Preference guide

Rule Specification

74 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

2

Maintainability

Write in a way so as not to cause modification errors.

Maintainability

2One of the patterns that bugs slip into a program is that another bug might be created by

mistake when fixing the detected bugs. Especially if it has been a while since the source code was written or if an engineer other than the creator modifies the source code, some unexpected misunderstandings might occur.

Efforts are required to reduce these modification errors as much as possible.

Maintaiability 2.1 Clarify the grouping of structured data and blocks.

Maintainability 2.2 Localize access ranges and related data.

75

1

Maintainability

Maintainability1●M2_Write in a way so as not to cause modification errors.

2

Maintainability

保保保

2.1 保保保保保保保保保保保保保保保保保保保保保保保保保保保

If arrays and structures are initialized with values oth-er than 0, their forms of structure shall be indicated using braces ‘{ }’ according to the forms. Data shall be described without any omissions, except when all values are 0.

M2.1.1

int arr1[2][3] = {{0, 1, 2}, {3, 4, 5}};int arr2[3] = {1, 1, 0};

int arr1[2][3] = {0, 1, 2, 3, 4, 5};int arr2[3] = {1, 1};

In initialization of arrays and structures, having a pair of brace is required at the minimum, but in this case, it is difficult to see how the initializing data are assigned. It is safer to make the initializing data into blocks according to the forms of the structure and write all the data without omission.

[Related rules] R1.2.1 M4.5.3

The body of if, else if, else, while, do, for, and switch statements shall be made into blocks.

M2.1.2

if (x == 1) { func();}

if (x == 1) func();

If the statement (body) controlled by an if statement etc. consists of multiple statements, they are nec-essary to be enclosed into a block. If there is only one controlled statement, it is not necessary to make it into a block, but when the single statement is replaced with multiple statements during program modifi-cations, enclosing them into a block may be forgotten. To prevent such modification errors, the body of each controlled statement should be enclosed into a block.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification

Preference guide ○

Rule Specification

M2.1 Clarify the grouping of structured data and blocks.

76 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

2

Maintainability

保保保

2.2 保保保保保保保保保保保保保保保保保保保保保

Variables used only in one function shall be declared within the function.

M2.2.1

void func1(void){ static int x = 0; if (x != 0) {  /* Refer to the value in the previous call */ x++; } …}void func2(void){ int y = 0; /* Initialize each time */ …}

int x = 0; /* x is accessed only from func1 */int y = 0; /* y is accessed only from func2 */void func1(void) { if ( x != 0 ) { /* Refer to the value in the previous call */ x++; } …}void func2(void) { y = 0; /* Initialize each time */ …}

For a variable declaration in functions, sometimes it is useful to put a static specifier to it. If static is specified, the following characteristics are attained.

- Static memory space is reserved and the space is valid until the end of the program (Without static, generally, stack memory is used and is valid until the end of the function.)

- Initialization occurs only once after the program is started and if a function is called more than once, the value assigned in the previous call is retained.

Therefore, among variables only accessed within a function those whose values to be retained even after the function terminates should be declared with static. In addition, if large memory space is declared for an automatic variable, it may cause stack overflow. In such case, static can be added to reserve static memory spaces even if the values are not required to retain after the function terminates. However, for this usage, explicitly stating the intention by comments etc. is recommended (as there is a risk of being misunderstood that the static is added by mistake).

[Related rule] M2.2.2

M2.2 Localize access ranges and related data.

Compliant example Non-compliant example

Preference guide ●

Rule Specification

77

1

Maintainability

Maintainability1●M2_Write in a way so as not to cause modification errors.

2

Maintainability

Variables accessed by several functions defined in the same file shall be declared with static in the file scope.

M2.2.2

/* x is not accessed by other files */static int x;void func1(void) { … x = 0; …}void func2(void) { … if (x == 0) { x++; } …}

/* x is not accessed by other files */int x;void func1(void) { … x = 0; …}void func2(void) { … if (x==0) { x++; } …}

The fewer the global variables are, the higher the readability is to understand the entire program. To re-tain the number of global variables, a static storage class specifier should be put as much as possible.

[Related rules] M2.2.1, M2.2.3

Functions that are called only by functions defined in the same file shall be as static.

M2.2.3

/* func1 is not called by functions in other files */static void func1(void) { …}void func2(void) { … func1(); …}

/* func1 is not called by functions in other files */void func1(void){ …}void func2(void){ … func1(); …}

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification

78 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

2

Maintainability

The fewer the global functions are, the higher the readability is to understand the entire program. To re-tain the number of global functions, a static storage class specifier should be put as much as possible.

[Related rule] M2.2.2

enum shall be used rather than #define when defin-ing related constants.

M2.2.4

enum ecountry { ENGLAND, FRANCE, …} country;enum eweek { SUNDAY, MONDAY, …} day;…if ( country == ENGLAND ) {if ( day == MONDAY ) {if ( country == SUNDAY ) { /*It is possible to check by tools*/

#define ENGLAND 0#define FRANCE 1#define SUNDAY 0#define MONDAY 1int country, day;…if ( country == ENGLAND ) {if ( day == MONDAY ) {if ( country == SUNDAY ) { /*It is impossible to check by tools*/

Enumeration types should be used when defining related constants like a set. Defining related constants with an enum type enables tools to check for incorrect usage. While macro names defined by #define are expanded at the preprocessing stage and the compiler does not process those names, enum constants defined by an enum declaration will be the names processed by the compiler. Names processed by the compiler are easier to debug as they can be referenced during symbolic debugging.

[Related rules] M1.10.1 P1.3.2

Compliant example Non-compliant example

Preference guide

Rule Specification

79

1

Maintainability

Maintainability1●M3_Write programs in a simple way.

3

Maintainability

Write program in a simple way. Maintainability

3As for software maintainability, nothing is better than software is written in a simple way. C language enables the structuring of software by dividing it into separate source files and

into functions etc. Structured programming is also one of the techniques to write software in a simple way that represents program structure through the three forms: sequence, selection and repetition. Try to write software in a simple way by taking advantages of the structuring of software. It should be noted that some writing styles of iteration processing, assignment or operations can make the program difficult to maintain.

Maintaiability 3.1 Do structured programming.

Maintaiability 3.2 One statement should have one side effect.

Maintaiability 3.3 Separately describe expressions with different purposes. 

Maintaiability 3.4 Do not use complicated pointer operations.

80 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

3

Maintainability

保保保

3.1 保保保保保保保保保保保保保保

For any iteration statement, there shall be at most one break statement used for loop termination.

【MISRA14.6】

M3.1.1

end = 0;for (i=0; loop iteration condition && !end; i++) {

Iterated processing 1; if (termination condition1 || termination condition2) { end = 1;

} else {Iterated processing 2;

}}-or-for (i=0; loop iteration condition; i++) {  Iterated processing 1;  if (termination condition1 || termination    condition2) { break; } Iterated processing 2; }

for (i=0; loop iteration condition; i++) { Iterated processing 1;

if (termination condition1) { break;

} if (termination condition1) {

break; } Iterated processing 2;}

This rule is to prevent the program logic from becoming complex. If a flag has to be prepared only for eliminating the break statement, sometimes it is better not to prepare the flag and to use a break state-ment. (Be careful that using an end flag shown in the Compliant example can complicate the program.)

M3.1 Do structured programming.

Compliant example Non-compliant example

Preference guide

Rule Specification

81

1

Maintainability

Maintainability1●M3_Write programs in a simple way.

3

Maintainability

(1)The goto statement shall not be used.(2) The goto statement shall be used only when

exiting multiple loops or when jumping to error handling.

M3.1.2

Compliant example of (1) and (2)for (i = 0; loop iteration condition; i++) { Iterated processing; }

Compliant example of (2)if (err != 0) { goto ERR_RET;} …ERR_RET: end_proc(); return err;}

Non-compliant example of (1) and (2) i = 0;LOOP: Iterated processing;

i++; if (loop iteration condition) { goto LOOP; }

This rule is to prevent the program logic from becoming complex. The purpose is not to do away with the goto statements, and it is important to eliminate unnecessary goto statements in order to avoid complicating the program (unable to read the program from top to bottom.) In some cases, using goto statements can help improve readability. Programs should be written with consideration to expressing the logic as simple as possible.

The continue statement shall not be used. 【MISRA 14.5】

M3.1.3

for (i = 0; loop iteration condition 1; i++) { Iterated processing 1; if (! iteration condition 2) { Iterated processing 2; }}

for (i = 0; loop iteration condition 1; i++) { Iterated processing 1; if (iteration condition 2) { continue; } Iterated processing 2;}

This rule is to prevent the program logic from becoming complex. The purpose is not to do away with the continue statements, and it is important to eliminate unnecessary continue statements in order to avoid complicating the program (unable to read the program from top to bottom.) In some cases, using continue statements can help improve readability. Programs should be written with consideration to expressing the logic as simple as possible.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification Choose

Preference guide

Rule Specification

82 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

3

Maintainability

M3.1.4

Compliant example of (1) and (2)switch (week) {case A: code = MON; break;case B: code = TUE; break;case C: code = WED; break;default: code = ELSE; break;}

Compliant example of (2)dd = 0;switch (status) {case A: dd++; /* FALL THROUGH */case B:

Non-compliant example of (1) and (2)/* No matter what the value of week is, code will be ELSE ==> bug */switch (week) {case A: code = MON;case B: code = TUE;case C: code = WED;default: code = ELSE;}

/* This situation allows case B processing to continue, but since there are no comments, it is non-compliant not only for (1) but also for (2) */dd = 0;switch (status) {case A: dd++;case B:

It is one of the most common coding errors to forget to put a break in switch statements in C lan-guage. Unnecessarily use of case clauses without a break should be avoided. When making the pro-gram to continue operation to the next case without a break statement, a comment should always be added to explicitly state that absence of the break statement is not a problem. What kind of comments to be inserted should be defined in the coding convention. For example, /* FALL THROUGH */ is often used.

a switch statement is not ended with a break statement, 《define a comment in your project 》 and insert that comment.

(1)Always end the case clauses and the default   clause in a switch statement with a break statement.

(2) When an case clause and the default clause in

Compliant example Non-compliant example

Preference guide ○

Rule Specification

ChooseDefine

83

1

Maintainability

Maintainability1●M3_Write programs in a simple way.

3

Maintainability

(1)Functions shall end with one return statement.(2) Return statements in the middle of a process

shall be only the cases for abnormal return.

M3.1.5

This rule is to prevent the program logic from becoming complex. If there are too many entry or exit points in the program, not only they complicate the program but also they make it difficult to set break points during debugging. For C language, there is only one entry point for a function but the exit points are where the return statements are written.

保保保

3.2 One statement should have one side effect.

(1)Comma expressions shall not be used.(2)Comma expressions shall only be used in initial-

ization expressions and update expressions of for statements.

M3.2.1

Compliant example of (1) and (2)a = 1;b = 1;

j = 10;for (i = 0; i < 10; i++) { … j--;}

Compliant example of (2)for (i = 0, j = 10; i < 10; i++, j--) { …}

Non-compliant example of (1) and (2)a = 1, b = 1;

Non-compliant example of (1)for (i = 0, j = 10; i < 10; i++, j--) { …}

Using comma expressions make the program complicated. However, an initialization expression and an update expression of a for statement are where operations to be executed before and after the loop are described together, and sometimes describing them collectively using a comma expression makes it easier to understand.

[Related rule] M3.3.1

M3.2 One statement should have one side effect.

Compliant example Non-compliant example

Preference guide

Rule Specification Choose

Preference guide

Rule Specification Choose

84 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

3

Maintainability

Multiple assignments shall not be described in one statement, except when the same value is assigned to multiple variables.

M3.2.2

x = y = 0; y = (x += 1) + 2;y = (a++) + (b++);

Assignments include the compound assignments (+=, -=, etc.) as well as the simple assignment (=).Mul-tiple assignments may be written in one statement, but it degrades readability so at most one assignment should be in one statement. However, “commonly used conventional descriptions” shown below do not impair readability in many cases. This rule may treat them as an exception.c = *p++;*p++ = *q++;

保保保

3.3 保保保保保保保保保保保保保保保保保

The three expressions of a for statement shall be concerned only with loop control. 【MISRA 13.5】

M3.3.1

for (i = 0; i < MAX; i++) { … j++;}

for (i = 0; i < MAX; i++, j++) { …}

[Related rules] M3.2.1, M3.3.2

M3.3 Separately describe expressions with different purposes.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide

Rule Specification

85

1

Maintainability

Maintainability1●M3_Write programs in a simple way.

3

Maintainability

Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.【MISRA 13.6】

M3.3.2

for (i = 0; i < MAX; i++) { …}

for (i = 0; i < MAX; ) { … i++;}

[Related rule] M3.3.1

(1)Assignment operators shall not be used in expressions to examine true or false.

(2)Assignment operators shall not be used in   expressions to examine true or false, except for conventionally used notations.

M3.3.3

Compliant example of (1) and (2)p = top_p;if (p != NULL) { …}

Compliant example of (1)c = *p++;while (c != '¥0') { … c = *p++;}

Non-compliant example of (1) and (2)if (p = top_p) { …}

Non-compliant example of (1) while (c = *p++) { …}/* This is OK for (2) as it is a conventionally used expression. (Good or bad depends on the programmers’ skills; Use with caution.) */

The following are the expressions to examine true or false: if (expression), for ( ;expression; ), while (expression), (expression)? :, expression && expression, expression || expression

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide

Rule Specification

Preference guide

Rule Specification Choose

86 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

3

Maintainability

保保保

3.4 保保保保保保保保保保保保保保保保

Pointer references of three or more levels shall not be used.

M3.4.1

int **p;typedef char **strptr_t;strptr_t q;

int ***p;typedef char **strptr_t;strptr_t *q;

Since it is difficult to understand the changes of pointer values in three or more levels of reference, it impairs maintainability.

M3.4 Do not use complicated pointer operations.

Compliant example Non-compliant example

Preference guide

Rule Specification

87

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

Write in a unified style.Maintainability

4Recently, program development by several developers has become popular. In such cases,

if each developer writes source code in different styles, problems occur such as a difficulty in reviewing for checking the contents of the code. In addition, if styles for naming variables and styles for describing the contents and their order of information in files are inconsistent, it can cause unexpected misunderstandings and errors. For this reason, it is recommended to unify how to write source code as much as possible in one project or organization.

Maintaiability 4.1 Unify coding styles.

Maintaiability 4.2 Unify how to write comments.

Maintaiability 4.3 Unify how to name.

Maintaiability 4.4 Unify description contents and their order in files.

Maintaiability 4.5 Unify how to write declarations.

Maintaiability 4.6 Unify how to write the null pointer.

Maintaiability 4.7 Unify how to write preprocessing directives.

88 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

保保保

4.1 保保保保保保保保保保保保保保保保

《Conventions regarding styles such as braces ({), in-dentation or how to insert spaces shall be defined.》

M4.1.1

It is important to unify coding styles in the project to make code easier to read. When determining a new style convention in your project, it is recommended to select from already ex-isting coding styles. There are several fashions for existing coding styles and many programmers write programs according to some of them. One advantage of choosing from existing styles is that their format can be specified easily by formatting commands in editors or other tools. If an existing project does not clearly specify a coding style, it is recommended to define a convention with the style that is closest to the current source code. Note that the most important issue when defining the style convention is “to define a unified one to fol-low”, not “what style to define.” The following are issues to be defined.

(1)The location of braces ({ })The location of braces should be unified to clarify the beginning and end of a block (see Typical styles)

(2)IndentationIndentation is to make a group of declarations and operations easier to see. Things to be defined to unify indentation are as follows:

 ・Whether to use spaces or tabs for indentation.  ・If spaces are used, how many space characters are set for one indent? If tabs are used, how many   characters are set for each tab?

(3)How to use space charactersSpace characters are inserted to make code easier to see and to make coding errors easier to spot. For example, define the following rules.

 ・Add a space before and after binary and ternary operators, except for the following operators.  [ ],  ->,  . (period),  , (comma operator)  ・Do not add a space between unary operator and its operand.

These rules make it easier to detect coding errors for compound assignment operators.

M4.1 Unify coding styles.

Preference guide ○

Rule Specification Define

89

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

  [Examples]  x = -1; /* An error where x-=1 is intended to be written => difficult to identify */

  x = - 1; /* An error where x-=1 is intended to be written => easy to identify */

Besides those stated above, the following rules can also be defined.

 ・Add a space after a comma (except for commas for parameters in macro definitions) ・Add a space before the left parenthesis enclosing control statements such as if and for. Do not   add a space before the left parenthesis for function calls.This rule makes it easier to identify function calls.

(4)Location of newlines for continuation linesWhen an expression becomes lengthy and goes beyond the length of one line seen easily, insert a new-line at an appropriate location. When inserting newlines, it is recommended to select one of the follow-ing two methods. What is important is to write a continuation line by indenting.

[Method1] Write an operator at the end of the line. Example: x = var1 + var2 + var3 + var4 +   var5 + var6 + var7 + var8 + var9; if (var1 == var2 &&   var3 == var4)

[Method2] Write an operator at the beginning of the continuation line. Example: x = var1 + var2 + var3 + var4   + var5 + var6 + var7 + var8 + var9; if (var1 == var2   && var3 == var4)

●Typical styles(1)K&R style

It is a coding style used in “The C Programming Language” (widely known as K&R). Like the nick-name of the book, the name is taken from the initials of the two authors. The locations of braces and indentation in the K&R style are as follows.

・Locations of braces. Braces for function definitions should be put at the beginning of a new line. Other braces (those in structures or control statements such as if, for and while) should be put on the same line without a newline (see the example).

・Indentation. One tab. The first edition of “The C Programming Language” set the width of a tab as 5 spaces, but the second edition (ANSI compliant) sets it as 4.

90 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

(2)BSD styleIt is a description style by Eric Allman who wrote many BSD utilities, and is also called the Allman style. The locations of braces and indentation in the BSD style are as follows.

・Locations of braces. All of function definitions, if, for and while etc. should start from a new line and the brace should be placed at the column aligned with the begin-ning of the previous line (see the example).

・Indentation.     8. 4 is also common.

(3)GNU styleIt is a coding style to write GNU packages. It is defined in “GNU Coding Standards” written by Richard Stallman and volunteers in the GNU project. The locations of braces and indentation in the GNU style are as follows.

・Locations of braces. All of function definition, if, for and while etc. should start from a new line. The braces for function definitions should be placed at column 0 and other braces should have an indent of 2 spaces (see the example).

・Indentation.     2. Braces and their body should both have 2-space indent.

(1)K&R style example:void func(int arg1){ /* { of a function starts after a newline */ /* Indent is one tab */ if (arg1) { … } …}

保保

(2)BSD style example:voidfunc(int arg1){ /* { of a function starts after a newline */ if (arg1) { … } …}

(3)GNU style example:voidfunc(int arg1){ /* { of a function starts after a newline at column 0 */ if (arg1) { … } …}

91

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

保保保

4.2 保保保保保保保保保保保保保保

《Conventions regarding how to write file header comments, function header comments, end of line comments, block comments and copyright shall be defined.》

M4.2.1

Writing good comments improves program readability. To make it better, the way of writing comments needs to be unified. There are document generation tools that create documents for maintenance and examination from the source code. When utilizing such tools, it is required to write in a way that follows their specifications. Generally, with document generation tools, descriptions of variables and functions under certain com-ment conventions in the source code are reflected in generated documents. Comment conventions should be defined by referring to the specifications of the tools. The following introduces information on how to write comments from existing coding conventions and books.

●Typical way of writing comments(1)Indian Hill coding conventions

The following comment rules are described in the Indian Hill coding standards.

・Block comments   They are used to describe data structures, algorithms, etc. The format is to write / in the first column,

all lines should have * in the second column and the end line should have */ in the second and the third columns. (Block comments can be extracted by grep ^.\*.)

 Example: /* Write comments * Write comments */

・Location of comments- Block comments inside a function

Write them in appropriate locations, for example by aligning with the indentation in the next line- End-of-line comments Start them apart from the statement using tabs. If more than one such comments appear, align them all be tabbe to the same tab setting.

(2)GNU coding standardsThe following comment rules are described in the GNU coding standards.

・Language  English.

M4.2 Unify how to write comments.

Preference guide ○

Rule Specification Define

92 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

・Location and contents - At the beginning of the program

Every program should start with comments that briefly explain what the program does.

  - Functions Write the following comments for each function. What the function does, explanation of parameters (values, meaning and purposes), return value

  - #endif Except for short conditions that are not nested, add comments at the end of the line of every #endif, to clarify the conditions.  - Notation for tools Place two spaces at the end of each comment sentence.

(3)“The Practices of Programming”The following comment rules are described in “The Practices of Programming.”

 ・Location Describe comments for functions and global data.

 ・Other practices

  - Don’t belabor the obvious.  - Don’t contradict the code.  - Clarify, don’t confuse

(4)Others  ・Include a copyright notice in comment. ・Define the comment for the switch statements without break. Example:

switch (status) { case CASE1: Processing; /* FALL THROUGH */ case CASE2: ・・・ 

 ・Define comments for no processing necessary. Example:

if (Condition 1) { Processing; } else if (Condition 2) { Processing; } else { /* DO NOTHING */ }

93

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

保保保

4.3 保保保保保保保保保保保保

《Conventions for naming external variables and in-ternal variables shall be defined.》

M4.3.1

See M4.3.2.

[Related rules] M1.7.1, M1.7.2, M1.7.3

《Conventions for naming files shall be defined.》M4.3.2

Readability of programs is greatly affected by naming. There are various methods for naming but im-portant points are to be consistent and to be easy to understand. For naming, the following items should be defined.

 ・Guidelines for names in general ・How to name files (including folders and directories) ・How to name globally and locally ・How to name macros etc.

The following introduces some naming guidelines and rules from existing coding conventions and books. They are useful as reference when creating new naming conventions in your project. If no nam-ing conventions is specifically defined by an existing project, it is recommended to create one that is closest to the current source code.

●Typical naming conventions(1)Indian Hill coding conventions ・Names with leading and trailing underscores are reserved for system purposes and should not be   used. ・#define constants should be in all CAPS.

M4.3 Unify how to name.

Preference guide ○

Rule Specification Define

Preference guide ○

Rule Specification Define

94 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

 ・enum constants are capitalized or in all CAPS. ・Avoid names that differ only in case, like foo and Foo. ・Global names should have a common prefix identifying the module that they belong with. ・The first character of file names should be a letter and characters should be lower-case letters and   numbers. The name should be eight or fewer characters (excluding the suffix.) ・Avoid private header filenames that are the same as library header filenames.

Overall ・Names with leading and trailing underscores should not be used.・Avoid names that differ only in case. Example: foo and Foo

Variable and function names

Global A prefix identifying the module should be added.

Local Nothing in particular

Other ・Macro names should be in all CAPS. Example: #define MACRO

・enum constants are Capitalized or in all CAPS.

(2)GNU coding standards ・Don’t choose terse names―instead, look for names that give useful information about the meaning   of the variable or function. Names should be English. ・Use underscores to separate words in a name. ・Stick to lower case; reserve upper case for macros and enum constants, and for name-prefixes that   follow a uniform convention.

Overall ・Use underscores to separate words in a name. Example: get_name

・ Stick to lower case; reserve upper case for macros and enum constants, and name-prefixes that follows a uniform convention.

Variable and function names

Global Don’t choose terse names―instead, look for names that give useful in-formation about the meaning of the variable and function. Names should be English.

Local Nothing in particular

Other ・Reserve upper case for macros. Example: #define MACRO

・Reserve upper case for enum constants.

(3)“The Practice of Programming” ・Use descriptive names for globals, short names for locals. ・Give related things and related names that show their relationship and highlight their difference. ・Function names should be based on active verbs, perhaps followed by nouns.

95

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

Overall Give related things and related names.

Variable and function names

Global Use descriptive names.

Local Use short names.

Other Function names should be based on active verbs, perhaps followed by nouns.

(4) Others・How to separate a name: A name that consists of multiple words should be either separated with

underscore or delimited using an uppercase letter for the first letters of the words. Determine which style to adopt.

・Hungarian notation: There is a notation called Hungarian notation that explicitly indicates the type of a variable etc.

・How to name files: Give a name with a prefix, for example, that expresses the subsystem.

保保保

4.4 保保保保保保保保保保保保保保保保保保保保保

《The contents (declarations, definitions, etc.) de-scribed in header files and their order shall be de-fined.》

M4.4.1

Items commonly used in a program should be described in header files as they have a risk of modifica-tion errors if described in several places. Header files should contain macro definitions, tag declarations for structures, unions and enumeration types, typedef declarations, external variable declarations and function prototype declarations that are commonly used in multiple source files. For example, they should be described in the following order:

 (1) File header comment (2) Inclusion of system headers (3) Inclusion of user defined headers (4) #define macros (5) #define function macros (6) typedef definitions (type definitions for basic types such as int or char) (7) enum tag definitions (together with typedef )  (8) struct/union tag definitions (together with typedef) (9) extern variable declarations (10)Function prototype declarations

Preference guide ○

Rule Specification Define

M4.4 Unify description contents and their order in files.

96 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

《The contents (declarations, definitions, etc.) de-scribed in source files and their order shall be de-fined.》

M4.4.2

In a source file, definitions of variables and functions, definitions or declarations of macros, tags, and types (typedef types) used only in the individual source file should be described. For example, they should be described in the following order:

 (1)File header comment  (2)Inclusion of system headers  (3)Inclusion of user-defined headers (4)#define macros used only in this file (5)#define function macros used only in this file (6)typedef definitions used only in this file (7)enum tag definitions used only in this file (8)struct/union tag definitions used only in this file (9)static variable declarations shared in this file (10)static function declarations (11)Variable definitions (12)Function definitions

*For (2) and (3), be careful not to include unnecessary items.*Avoid describing (4) through (8) as much as possible.

Preference guide ○

Rule Specification Define

97

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

To use or define external variables or functions (ex-cept for functions used only in the file), the header file describing their declarations shall be included.

M4.4.3

--- my_inc.h ---extern int x;int func(int);

--------------#include "my_inc.h"int x;int func(int in){ …

/* There is no declaration for variable x and function func */int x;int func(int in){ …

In C language, variables should either be declared or defined before being used. On the other hand, functions can be used without declarations or definitions. However, it is recommended to describe dec-larations in a header file and include that header file in order to maintain consistency of declarations and definitions.

External variables shall not be defined in multiple lo-cations.

M4.4.4

int x; /* Definition of one external variable should be only once */

int x;int x; /* Definition of an external variable in multiple locations does not cause a compile error */

Definitions without initialization for external variables can be described more than once. However, the behavior is not guaranteed when an external variable is initialized in multiple files.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ●

Rule Specification

98 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

Variable definitions or function definitions shall not be described in a header file.

M4.4.5

--- file1.h ---extern int x; /* Variable declaration */int func(void); /* Function declaration */

--- file1.c ---#include "file1.h"int x;       /* Variable definition */int func(void) /* Function definition */{ …}

--- file1.h ---int x; /* External variable definition */static int func(void) /* Function definition */{ …}

Header files might be included into several source files. Therfore, describing variable definitions and function definitions in a header file may unnecessarily enlarge object code size generated after compila-tion. Basically, only declarations or type definitions should be described in a header file.

Header files shall be written so as to handle redun-dant inclusions.《A way of writing to achieve this shall be defined.》

M4.4.6

--- myheader.h ---#ifndef MYHEADER_H#define MYHEADER_H  Contents of the header file#endif /* MYHEADER_H */

--- myheader.h ---void func(void);/* end of file */

Header files should be organized as much as possible to avoid redundant inclusions. However, in spite of such efforts, there are cases for redundant inclusions. To prepare for this, it is necessary for a header file to have a means that can handle multiple inclusions. For example, this rule may be as follows.Example of the rule:At the beginning of a header file, write a #ifndef macro that judges whether the header has already been included or not so that the following description will not be compiled in the subsequent inclusions. The macro name for this should be the header file name in all uppercase letters with _ (underscore) re-placing the period.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide ○

Rule Specification Define

99

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

保保保

4.5 保保保保保保保保保保保保

M4.5.1

Compliant example of (1)int func1(int, int);

int func1(int x, int y){ /* Processing of the function */}

Compliant example of (2)int func1(int x, int y);int func2(float x, int y);

int func1(int x, int y){ /* Processing of the function */}

int func2(float x, int y){ /* Processing of the function */}

Non-compliant example of (1) and (2)int func1(int x, int y);int func2(float x, int y);

int func1(int y, int x) /* Parameter name is different from the name in the prototype declaration */{ /* Processing of the function */}

typedef int INT;int func2(float x, INT y) /* The type of y is not literally the same as in the prototype declaration */{ /* Processing of the function */}

In a function prototype declaration, parameter names can be omitted, but describing appropriate parame-ter names is useful as function interface information. When describing parameter names, the same name as in the definition should be used to avoid unnecessary confusion. As for the types of the parameters, it is also recommended that they are literally the same as in the function definition to make it easier to understand.

[Related rules] M1.4.1

M4.5 Unify how to write declarations.

(1)In a function prototype declaration, all the pa-rameters shall not be named (types only.)

(2)In a function prototype declaration, all the pa-rameters shall be named. In addition, the types of the parameters, their names and the type of the return value shall be literally the same as those of the function definition.

Compliant example Non-compliant example

Preference guide ○

Rule Specification Choose

100 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

Structure tags and variables shall be declared sepa-rately.

M4.5.2

struct TAG { int mem1; int mem2;};struct TAG x;

struct TAG { int mem1; int mem2;} x;

M4.5.3

Compliant example of (1)struct tag data[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } /* There is no comma after the last element */};Compliant example of (2)struct tag data[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, /* There is a comma after the last element */

Non-compliant example of (1) and (2)struct tag x = { 1, 2, };/* It is unclear whether there are two members only or there are three or more members*/

For initialization of multiple data, there are two styles: one is not to put a comma after the last initial value to explicitly state the end of initialization, the other is to put a comma at the end in consideration of ease of additions and deletions of initial values. Consider which way to focus on and determine the rule. In C90 standard, it was not acceptable to have “,” just before “}” that indicates the end of an enumera-tor list, but this became acceptable in C99 standard.

[Related rule] M2.1.1

(2) “,” shall not be put before the last “}” in the list of initial value expressions for structures, unions and arrays, nor in the list of enumerators. However, to put “,” before the last “}” in the list of initial values for array initialization is allowed.

(1) “,” shall not be put before the last “}” in the list of initial value expressions for structures, unions and arrays, nor in the list of enumerators.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification Choose

Preference guide

Rule Specification

101

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

保保保

4.6 保保保保保保保保保保保保保保保保

(1) 0 shall be used for the null pointer. NULL shall not be used in any case.

(2) NULL shall be used for the null pointer. NULL shall not be used for anything other than the null point-er.

M4.6.1

Compliant example of (1)char *p;int dat[10];

p = 0;dat[0] = 0;

Compliant example of (2)char *p;int dat[10];

p = NULL;dat[0] = 0;

Non-compliant example of (1)char *p;int dat[10];

p = NULL;dat[0] = NULL;

Non-compliant example of (2)char *p;int dat[10];

p = 0;dat[0] = NULL;

NULL is an expression conventionally used as the null pointer, but the expression of the null pointer is different depending on execution environments. For this reason, some people think that it is safer to use 0.

M4.6 Unify how to write the null pointer.

Compliant example Non-compliant example

Preference guide ○

Rule Specification Choose

102 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

保保保

4.7 保保保保保保保保保保保保保保保

The body and the parameters of a macro that has operators shall be enclosed with parentheses.

M4.7.1

#define M_SAMPLE(a, b) ((a)+(b)) #define M_SAMPLE(a, b) a+b

If the macro body and the parameters are not enclosed with parentheses, after expanding the macro, a bug may occur as the operation order may not be what is expected depending on the precedences of op-erators next to the macro and operators in the macro.

#else or #endif that correspond to #ifdef, #ifndef and #if shall be described in the same file and their correspondence shall be clearly stated with a com-ment 《defined in the project.》

M4.7.2

#ifdef AAA/* Process when AAA is defined */ …#else /* not AAA *//* Process when AAA is not defined */ …#endif /* end AAA */

#ifdef AAA/* Process when AAA is defined */ …#else/* Process when AAA is not defined */ …#endif

If #else or #endif is described in distant locations or nested in a partitioned process by macros such as #ifdef, their correspondence becomes difficult to understand. Comments should be added to #else and #endif that make their correspondence to #ifdef etc. easier to understand.

[Related rules] M1.1.1, M1.1.2

M4.7 Unify how to write preprocessing directives.

Preference guide ○

Rule Specification Define

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

103

1

Maintainability

Maintainability1●M4_Write in a consistent way.

保保保

4

4

Maintainability

“defined (macro name)” shall be used to check whether a macro name has already been defined by #if. Writing “#if macro name” shall not be used.

M4.7.3

#if defined(AAA)…#endif

#if AAA …#endif

“#if macro name” does not determine whether a macro is defined or not. The judgment will be false not only when the macro is not defined but also when the macro is defined and its value is 0. defined should be used to check whether a macro is defined or not.

defined operator used in #if and #elif shall be writ-ten as “defined (macro name)” or “defined macro name”, and not in any other way.

M4.7.4

#if defined(AAA) …#endif

#define DD(x) defined(x)#if DD(AAA)…#endif

In the C language standard, if writing styles other than “defined (macro name)” or “defined macro name” are used for the defined operator, their handling is undefined. Such writing styles should not be used because a compiler may make it an error or another may interpret it in its own way.

Preference guide

Rule Specification

Preference guide ●

Rule Specification

Compliant example Non-compliant example

Compliant example Non-compliant example

104 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

4

Maintainability

Macros shall not be #define’d or #undef’d within a block. 【MISRA 19.5】

M4.7.5

#define AAA 0#define BBB 1#define CCC 2struct stag { int mem1; char *mem2;};

/* Members that have restrictions on the assigned values exist */struct stag { int mem1; /* The following values can be assigned */#define AAA 0#define BBB 1#define CCC 2 char *mem2;};

In general, macro definitions (#define) should be described all together at the beginning of a file. If they are spread throughout the file by describing them within blocks etc., the readability will be degraded. In addition, cancelling (#undef) definitions within a block will also degrade the readability. Note that unlike variables, the scope of macro definitions is up to the end of the file. The program in the non-compliant example can be changed in the following way:

enum etag { AAA, BBB, CCC };struct stag { enum etag mem1; char *mem2;};

[Related rule] M4.7.6

#undef shall not be used.【MISRA 19.6】M4.7.6

A #define’d macro name can be an undefined state with #undef, but the readability is degraded as there is a risk that its interpretation may differ depending on where the macro name is referred.

[Related rule] M4.7.5

Preference guide

Rule Specification

Preference guide

Rule Specification

Compliant example Non-compliant example

105

1

Maintainability

Maintainability1●M5_Write in a way easy to test.

5

Maintainability

Write in a way easy to test.Maintainability

5One of the fundamental tasks in embedded software developments is to check the behavior

(test). However, recent complex embedded software may have problems where bugs and malfunctions detected during tests cannot be reproduced etc. Therefore, when writing source code, it is desirable to consider even ease of problem cause analysis. Especially, dynamic memories should be used with special care, because they have risks such as causing memory leaks.

Maintaiability 5.1 Write in a way that is easy to investigate the cause of

problems.

Maintaiability 5.1 Be careful when using dynamic memory allocations.

106 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

5

Maintainability

保保保

5.1 保保保保保保保保保保保保保保保保保保保保保保

《A way of coding for setting debug options and writ-ing logs in release modules shall be defined.》

M5.1.1

Besides correctly implementing specified functions, it is necessary to write program code with con-sideration to ease of debugging and investigation in case of occurrence of problems. Descriptions for facilitating investigation of problems include debug descriptions which are not reflected in the release module and post release log output descriptions which are reflected in the release module. The following explains how to determine rules for each description.

●Descriptions for debugDebug descriptions such as print statements used during program development should be written not to be included in the release module. This section explains how to isolate the code using macro definitions and how to use assert macros for debugging purpose.

(a) Using macro definitions to isolate debug descriptions Macro definitions should be used to identify the code parts to be compiled so that the debug descriptions are not reflected in the provided release module. Strings such as “DEBUG” or “MODULEA_DEBUG” that contain “DEBUG” are commonly used as those macro names.

Example of rule definition:The debug code is isolated with #ifdef DEBUG (the DEBUG macro should be specified at compile time).

[Code example] #ifdef DEBUG fprintf(stderr, "var1 = %d/n", var1); #endif

The following macro definitions can also be used.

Example of rule definition:The debug code is isolated with #ifdef DEBUG (the DEBUG macro should be specified at compile time). And the following macro should be used to output debug information.

  DEBUG_PRINT(str); /* Output str to standard output */

Since this macro is defined in debug_macros.h the common header of the project, the header should be included to use this function.

M5.1 Write in a way that is easy to investigate the cause of problems.

Preference guide ○

Rule Specification Define

107

1

Maintainability

Maintainability1●M5_Write in a way easy to test.

5

Maintainability

-- debug_macros.h -- #ifdef DEBUG #define DEBUG_PRINT(str) fputs(str, stderr) #else #define DEBUG_PRINT(str) ((void) 0) /* no action */ #endif /* DEBUG */

[Code example] void func(void) { DEBUG_PRINT(">> func\n"); ・・・ DEBUG_PRINT("<< func\n");}

(b) Using the assert macroThe C language standard provides the assert macro as a program diagnostic function. The assert macro is useful as it facilitates detecting mistakes in the program during debugging. By defining to unify where to use assert macros in a project, the consistent debug information can be collected during the in-tegration test etc. and make debugging easier. The following is a simple explanation of using the assert macro. This is a coding for a function defini-tion, for example, written under the precondition that the null pointer is never passed as the argument.

void func(int *p) { assert(p != NULL); *p = INIT_DATA; ・・・}

If the NDEBUG macro is defined at compile time, the assert macro does notify. On the other hand, if the NDEBUG macro is not defined and the expression passed to the assert macro is false, the program abends after outputting the file name and the line number of the source to the standard error. Note that the mac-ro name is NDEBUG, not DEBUG.

The assert macro is a macro provided by the compiler in assert.h. Refer to the following and examine how to abort the program and then determine whether to use the macro provided by the compiler or to provide your own assert function.

#ifdef NDEBUG#define assert(exp) ((void) 0)#else#define assert(exp) (void) ((exp)) || (_assert(#exp, __FILE__, __LINE__)))#endif

void _assert(char *mes, char *fname, unsigned int lno) { fprintf(stderr, "Assert:%s:%s(%d)¥n", mes, fname, lno); fflush(stderr); abort();}

108 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

5

Maintainability

● Outputting logs after releaseIt is also useful to include descriptions for problem investigation in the release module that do not con-tain descriptions for debug. The common method is to log the investigation information. The log infor-mation is helpful for validation tests for the release module or for investigation of problems occurred in the system provided to a customer. To record the log information, the following items should be determined and defined as rules.

 ・When to output logs

   Logs should be output not only when abnormal conditions are found, but also when, for example, send or receive with an external system occurs, to be able to trace the history to investigate why the abnormal condition occurred.

 ・What to output in logs

   The information that enables to trace the history to investigate why the abnormal condition oc-curred, such as previously executed processes, previous data values or trace information of memory should be recoded.

 ・A macro or a function to output information

   Localize outputting log information as a macro or a function, as it is often preferable that the output destination of logs can be changed.

(1) The # and ## preprocessor operators should not be used.【MISRA 19.13】(2) There shall be at most one occurrence of the # or ## preprocessor operators in a single macro definition.【MISRA 19.12】

M5.1.2

Compliant example of (1)#define AAA(a, b) a#b#define BBB(x, y) x##y

Non-compliant example of (1) and (2)#define XXX(a, b, c) a#b##c

The evaluation order of # operator and ## operator is not defined. Therefore, # and ## operators should not be mixed nor used twice or more.

Preference guide

Rule Specification Choose

Compliant example Non-compliant example

109

1

Maintainability

Maintainability1●M5_Write in a way easy to test.

5

Maintainability

Functions shall be used rather than function-like macros.

M5.1.3

int func(int arg1, int arg2){ retrun arg1 + arg2;}

#define func(arg1, arg2) (arg1 + arg2)

Using functions rather than function-like macros facilitates tracking processes by stopping at the begin-ning of a function during debugging etc. In addition, the compiler performs type checking with the functions and helps to detect coding mistakes.

[Related rule] E1.1.1

保保保

5.2 保保保保保保保保保保保保保保保保保保保保

(1) Dynamic memories shall not be used.(2) If dynamic memories are used, 《the maximum used memories, processes in case of insufficient memories, and debugging procedures shall be defined.》

M5.2.1

Using dynamic memories involves the risk of a memory leak that uses up the system resources by ac-cessing invalid memories or by forgetting to return memories to the system. If using dynamic memories is required, it is better to define rules to facilitate debugging. Some compilers provide functions for debug shown below. First, check the compiler used. Open source software also has pieces of source code for debug and they are useful as references when creating your own.

Example of rule definition:To obtain and return dynamic memories, do not use standard functions such as malloc or free, but X_MALLOC and X_FREE functions provided by the project should be used. Code for debug should be cre-ated by compiling the source with -DDEBUG option.

M5.2 Be careful when using dynamic memory allocations.

Preference guide

Rule Specification

Preference guide

Rule Specification

ChooseDefine

Compliant example Non-compliant example

110 Part2_Coding Practices for Embedded Software:Practices Chart

1

Maintainability

5

Maintainability

-- X_MALLOC.h --#ifdef DEBUGvoid *log_malloc(size_t size, char*, char*);void log_free(void*);#define X_MALLOC(size) log_malloc(size, __FILE__, __LINE__)#define X_FREE(p) log_free(p, __FILE__, __LINE__)#else#include <stdlib.h>#define X_MALLOC(size) malloc(size)#define X_FREE(p) free(p)#endif

[Code example] #include "X_MALLOC.h"…p = X_MALLOC(sizeof(*p) * NUM);if (p == NULL) { return (MEM_NOTHING);}…X_FREE(p);return (OK);

● Reference: Problems when using dynamic memories The following are problems that are likely to occur when using dynamic memories.

 ・Buffer overflow    To read or update areas beyond the range of obtained memory, especially if an area outside the

range is accidentally updated, the failure problem does not occur at the time of update but will oc-cur when the memory destroyed by the update is referenced. The trouble with dynamic memories is that it is very difficult to find where the memory is destroyed.

 ・Omission of initialization

   Memories obtained by typical dynamic memory functions are not initialized (there are some dy-namic memory obtaining functions perform initialization.) Like automatic variables, the memories should be initialized in the program before using them.

 ・Memory leaks

   They are caused by memories that have been forgotten to be returned. They do not cause a problem with a program that terminates each time. However, with a program that keeps running, memory leaks can be the cause of memory depletion and system malfunction.

 ・Use after return   If memories are returned using the free function etc., those memories may be reused by malloc

functions called afterwards. Therefore, an update using the address of the free’d memory will destroy the memory used for another purpose. As explained in the case of buffer overflow, it is ex-tremely difficult to debug this problem.

The code that leads to these problems does not cause compilation errors. In addition, problems do not occur at the location where the bug is embedded, thus they cannot be detected by tests that check with normal specifications. They cannot be debugged unless code reviews or tests by inserting test code or including special libraries to discover these problems are performed.

One of the characteristics of embedded software is that there are various options for platforms on which it operates. That is, there are many possible combinations of MPU options for the hardware platform and OS options for the software platform. As functions realized by the embedded software increase, op-portunities to port the existing software to other platforms are increasing by making one piece of software to be adapted on dif-ferent platforms.In such a situation, software portability becomes an extremely important element also at the source code level. In particular, writing in a style that depends on compilers is one of the most common mistakes.

●Portability 1: Write in a compiler independent way.●Portability 2: Localize code with portability issues.

Portability

112

信信信

セセセセセ

Part2_Coding Practices for Embedded Software:Practices Chart

1

Portability

Write in a compiler independent way.

Portability

1Use of compilers (processing systems) is unavoidable when programming in C language.

There are various processing systems in the world and each has its own features. If the source code is written in a bad manner, it may depend on the features of the processing system and may cause unexpected results when using another processing system.

For this reason, it is necessary to be sure to write in a way independent from processing systems when programming.

Portability 1.1 Do not use advanced functionalities or implementation-defined functionalities.

Portability 1.2 Use only characters and escape sequences defined in the language standard.

Portability 1.3 Confirm and document representations for data types, behavioral specifications of advanced functionalities and implementation-dependent parts.

Portability 1.4 Confirm implementation-dependent parts for source file in clusion, and write implementation-independent inclusions.

Portability 1.5 Write in a way that does not depend on the compilation environment.

113Portability1● P1_Write in a compiler independent way.

1

Portability

セセセ

1.1 セセセセセセセセセセセセセセセセセセセセ

(1) Functionalities not specified in the C90 standard shall not be used.

(2) If functionalities not specified in the C90 stan-dard are used, 《document the functionalities to be used and their usage.》

P1.1.1

The C90 standard does not support functionalities such as // comment or long long type, that are pro-vided in recent compilers and defined in the C99 standard.It is also realistic to choose the rule (2) and allow to use the functionalities defined in the C99 standard.The following related rules explain the details of how to use nonstandard functionalities. This rule shows a guiding principle.

[Related rules] P1.1.3, P1.2.1, P1.2.2, P1.3.2, P2.1.1, P2.1.2

《All usage of implementation-defined behavior shall be documented.》【MISRA 3.1】

P1.1.2

In C90, there are 41 implementation-defined items excluding in the library chapter. For example, the fol-lowing are implementation-defined and should be documented if they are used.

・How to represent floating-point numbers・How to handle signs of remainders for integer division・The search order of files for the #include directive ・#pragma

Also refer to Appendix C “Implementation-defined documentation template.”

P1.1 Do not use advanced functionalities or implementa-tion-defined functionalities.

Preference guide

Rule Specification

ChooseDocument

Preference guide ○

Rule Specification Document

114

信信信

セセセセセ

Part2_Coding Practices for Embedded Software:Practices Chart

1

Portability

To use a program written in another language, 《its interface shall be documented and its usage shall be defined.》

P1.1.3

The C language standard does not define the interface for using programs written in other languages from a C language program. That is, using a program written in another language means using an ad-vanced functionality, which lacks the portability. If such a program is used, the compiler specification for the interface should be documented and its usage should be defined regardless of the possibility of porting.

セセセ

1.2 セセセセセセセセセセセセセセセセセセセセセセセセセセセ

To use characters other than those defined in C90 for writing a program, the compiler specifications shall be confirmed 《and their usage shall be de-fined.》

P1.2.1

The basic character set defined in C90 to be used in source code are the 26 uppercase letters and the 26 lowercase letters of the Latin alphabet, the 10 decimal digits, the 29 graphic characters, the space charac-ter, and control characters representing horizontal tab, vertical tab, and form feed. In Japan, many com-pilers accept strings and comments written in Japanese, but they might cause problems and should be used with care. For example, since the second byte of “ 表 ” in Shift_JIS character code is ‘\’ in ASCII code, it might be taken as a line concatenation if // comment is used.

  int index_arr[10]; // インデックス表

  int *index_ptr = index_arr; // This line may be concatenated to the previous line.

To use characters not defined in C90 (Japanese, for example,) confirm that they can be used in the fol-lowing locations and define their usage.

・Comments・String literals

P1.2 Use only characters and escape sequences defined in the language standard.

Preference guide

Rule Specification

Document Define

Preference guide

Rule Specification Define

115Portability1● P1_Write in a compiler independent way.

1

Portability

- Processing when \ exists in the character codes of the string (whether special care is required or whether options are required at compile time etc.)

- The necessity to write using wide string literals (with the prefix L such as L“string”.)・Character constants

- The bit length of the character constant- The necessity to write using wide character constants (with the prefix L such as L‘あ’).

・The file name of #include

For example, define the following rules.

- Comments can be written in Japanese. The character code used should be Shift_JIS. Half-width kana should not be used.

- Japanese should not be used in strings, string constants and file names of #include.

[Related rule] P1.1.1

Only escape sequences defined in the language standard shall be used.

P1.2.2

char c = '\t'; /* OK */ char c = '\x'; /* Non-compliant: Escape sequence not defined in the language standard. Many processing systems interpret it as x, but there is no portability */

C90 defines the following seven escape sequences including the new-line (\n). \a \b \f \n \r \t \v

If undefined escape sequences are contained in a character constant or a string literal, the behavior is not defined. (See C90 6.1.3.4.)

[Related rule] P1.1.1

Compliant example Non-compliant example

Preference guide

Rule Specification

116

信信信

セセセセセ

Part2_Coding Practices for Embedded Software:Practices Chart

1

Portability

セセセ

1.3 セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セセセセセセセセセセセセセセセ

P1.3.1

char c = 'a'; /* Used to store characters */int8_t i8 = -1; /* To use it as 8bits data, use a type defined with typedef, for example. */

char c = -1;if (c > 0) { … }/* Non-compliant: Depending on processing systems, char can be signed or unsigned and this difference affects the result of the comparison. */

Unlike other integer types such as int, char without specifying sign will be either signed or unsigned depending on the compiler. (int is the same as signed int.) Therefore, using char that depends on the specification of the sign is not portable. This is because char without sign specification is an independent type (that is, char, unsigned char and signed char are three different types) provided for storing characters and the language standard assumes such usage. For a small integer type that requires pro-cesses dependent on the presence of a sign, for example, unsigned char or signed char specifying the sign should be used. In this case, it is desirable to use the type as a typedef to localize the range of modification during porting.A similar problem regarding this rule is that the returned type of the standard function getc is int and should not be received by char. However, this is a function interface problem (an assignment that may cause an information loss.)

The members of an enumeration type (enum) shall be defined with values that can be represented as int type.

P1.3.2

/* If int is 16bits and long is 32bits */enum largenum { LARGE = INT_MAX};

/* If int is 16bits and long is 32bits */enum largenum { LARGE = INT_MAX+1};

P1.3Confirm and document representations for data types, be-havioral specifications of advanced functionalities and imple-mentation-dependent parts.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Simple char type (signed or unsigned not specified) shall be used only for (processes of) storing char-acter values. If a process that depends on signed or unsigned (implementation-defined) is required, unsigned char or signed char specifying its sign shall be used.

Preference guide

Rule Specification

117Portability1● P1_Write in a compiler independent way.

1

Portability

In the C language standard, the members of an enumerated type must have values that can be represent-ed as int type. However, some compilers extend this specification and may not cause an error even if the value exceeds the range of int type.

Reference C++ allows values in the range of long type.

[Related rule] P1.1.1

P1.3.3

Compliant example of (2)struct S { unsigned int bit1:1; unsigned int bit2:1;};extern struct S * p; /* OK, if p points to a date that is, for example, just a set of flags and bit1 can be any bit in that data. */p->bit1 = 1;

Non-compliant example of (2)struct S { unsigned int bit1:1; unsigned int bit2:1;};extern struct S * p; /* If the bit positions are meaningful, for example, when p points to IO ports; that is, whether bit1 is the lowest or the highest bit of the data is meaningful, the program does not have portability. */

p->bit1 = 1; /* Which bit in the data that p points to is set is implementation-dependent */

The behaviors of bit fields shown below differ depending on compilers used.

(1) Whether bit fields of an int type without sign specification are handled as signed(2) The assignment order of the bit fields within a unit(3) The boundary of a bit field in a storage unit

If bit fields are used to access data whose bit positions are meaningful such as accessing to IO ports, it will cause a portability problem with regard to (2) and (3). Therefore, in such cases, not bit fields but bit-wise operations such as & and | should be used.

[Related rule] R2.6.1

Compliant example Non-compliant example

Preference guide ○

Rule Specification

ChooseDocument

(1) Bit fields shall not be used.(2) Bit fields shall not be used for data whose bit positions are meaningful.(3)《If it is being relied upon, the implementation-

defined behavior and packing of bit fields shall be documented.》【MISRA 3.5】

118

信信信

セセセセセ

Part2_Coding Practices for Embedded Software:Practices Chart

1

Portability

セセセ

1.4 セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セ セセセセセセセセセセセセセセセセセ

The #include directive shall be followed by either a <filename> or “filename” sequence.

【MISRA 19.3】

P1.4.1

#include <stdio.h>#include "myheader.h"#if VERSION == 1#define INCFILE "vers1.h"#elif VERSION == 2#define INCFILE "vers2.h"#endif#include INCFILE

#include stdio.h /* It has neither <> nor “” */#include "myheader.h" 1 /* 1 is specified at the end */

In the C language standard, the behavior is not defined (undefined) for the situation when a string after a #include directive after macro-expansion does not match either of the two styles of header names (<....> or "...."). Most compilers cause an error if it does not match either of the two styles, but some compilers may not cause an error, so write in either of the two styles.

《The usage of <> format and “” format for #include file specification shall be defined.》

P1.4.2

#include <stdio.h>#include "myheader.h"

#include "stdio.h"#include <myheader.h>

There are two ways to write a #include. To unify the usage, define rules such as the following for ex-ample.

・Specify headers provided by the compiler enclosed with < >・ Specify headers created by the project enclosed with “”・ Specify headers provided by purchased software enclosed with “”

P1.4Confirm implementation-dependent parts for source file in-clusion, and write implementation-independent inclusions.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ●

Rule Specification

Preference guide

Rule Specification Define

119Portability1● P1_Write in a compiler independent way.

1

Portability

Characters ‘, \, “, /*, and : shall not be used for the file specification in #include.

P1.4.3

#include "inc/my_header.h" /* OK */ #include "inc¥my_header.h" /* Non-compliant */

If above characters are used (more specifically, in the following cases), the behavior is not defined in the C language standard. That is, the operation result is uncertain, so it does not have portability.

・When characters ', \, “ or /* appear among the string enclosed with < >・When characters ', \ or /* appear among the string enclosed with “”

Also, the behavior of the character : (colon) differs depending on the system, and it does not have porta-bility.

セセセセセセセセセセセセセセセセセセセセ

The absolute path shall not be written for the file specification in #include.

P1.5.1

#include "h1.h" #include "/project1/module1/h1.h"

If an absolute path is written in the code, modification to the path is required when the program is com-piled with directories changed.

P1.5 Write in a way that does not depend on the compi-lation environment.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ○

Rule Specification

Preference guide

Rule Specification

120

信信信

セセセセセ

Part2_Coding Practices for Embedded Software:Practices Chart

1

Portability

2

Portability

Localize code that has portability problems.

Portability

2The principle is not to write implementation-dependent source code as much as possible,

but in some cases, this may not be possible. A typical example is when assembly language programs are called from C language. For these cases, it is recommended to localize such parts of code as much as possible.

Portability 2.1 Localize code that has portability problems.

121

1

Portability

Portability2●P2_ Localize code with portability issues.

2

Portability

セセセ

2.1 セセセセセセセセセセセセセセセセセセセ

P2.1.1

#define SET_PORT1 asm(" st.b 1, port1")void f() { … SET_PORT1; …}

void f() { … asm(" st.b 1,port1"); …}/* asm and other processes are mixed */

Many processing systems support the asm (string) format extendedly as a method to include assembly language code. However, there are some systems that do not support the feature, and even if it is sup-ported with the same format, its behavior may differ from system to system, so it does not have portabil-ity.

[Related rules] P1.1.1, P1.1.3

Extended keywords provided by the processing system shall be localized to use 《by defining mac-ros》.

P2.1.2

/* interrupt is a keyword extended by the system. */#define INTERRUPT interruptINTERRUPT void int_handler (void) { …}

/* interrupt is a keyword extended by the system. It is used without being defined by a macro */interrupt void int_handler(void) { …}

Some compilers provide extended keywords instead of using the #pragma directive, but using such key-words does not have portability. When using them, it is important to localize their use by defining them as macros. As shown in the example, their macro names are often the keywords in uppercase letters.

[Related rule] P1.1.1

P2.1 Localize code that has portability problems.

Preference guide ○

Rule Specification Define

Preference guide ○

Rule Specification Define

When assembly language programs are called from C language, 《how to localize such parts shall be defined》 by, for example, expressing them as functions of C language that contain only inline assembly lan-guage code or describing them using macros.

Compliant example Non-compliant example

Compliant example Non-compliant example

122

信信信

セセセセセ

Part2_Coding Practices for Embedded Software:Practices Chart

1

Portability

2

Portability

P2.1.3

Compliant example of (1) and (2)uint32_t flag32; /* Use unit32_t if 32bits is assumed */

Compliant example for (2) int i:for (i = 0; i < 10; i++) { … }/* i is used as an index. It can be 8bits, 16bits or 32bits and a basic type in the language specification can be used for i */

Non-compliant example of (1) and (2)unsigned int flag32; /* used by assuming int as 32bits */

The sizes and internal representations for each integer types of char, short, int, and long are differ-ent depending on the compiler. C99 specifies to provide the following typedefs as the language standard, so it is advisable to refer to them as names for typedef.

 int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t

[Related rule] P1.3.1

Preference guide ○

Rule Specification

ChooseDocument

(1) The basic types such as char, int, long, float, and double shall not be used. Instead, types defined by typedef shall be used. 《The types defined by typedef to be used in the project shall be defined.》

(2) If the basic types such as char, int, long, float, and double are used in a form that depends on their sizes, types defined by typedef for each of the basic types shall be used. 《The types defined by typedef to be used in the project shall be defined.》

Compliant example Non-compliant example

A characteristic of embedded software is that it is embed-ded in a product to operate with hardware in the real world. Various restrictions on MPUs or memories are also imposed on the software to cut down the cost of the product. In addition, a strict time constraint should be satisfied to meet real-time requirement etc. Embedded software re-quires coding thoughtful of resource efficiency for memo-ries etc., and time efficiency in consideration of the time performance.

●Efficiency1: Write with careful attention to resource and time efficiencies.

Efficiency

124 Part2_Coding Practices for Embedded Software:Practices Chart

1

Efficiency

Write with careful attention to resource and time efficiencies.

Efficiency

1Depending on how the source code is written, object size may increase or execution speed

may decrease. If there are restrictions on memory size and processing time, extra effort is required to write code considering such restrictions.

Efficiency 1.1 Write with careful attention to resource and time ef-ficiencies.

125Efficiency1● E1_Write with careful attention to resource and time efficiencies.

1

Efficiency

効効効

1.1 効効効効効効効効効効効効効効効効効効効効

Macro functions shall be used only in parts related to speed performance.

E1.1.1

extern void func1(int,int); /* Function */#define func2(arg1, arg2) /* Macro function */

func1(arg1, arg2);for (i = 0; i < 10000; i++) { func2(arg1, arg2); /* Processing where speed performance is important */}

#define func1(arg1, arg2) /* Macro function */extern void func2(int, int); /* Function*/

func1(arg1, arg2);for (i = 0; i < 10000; i++) { func2(arg1, arg2); /* Processing where speed performance is important */}

Functions are safer than macro functions and should preferably be used. However, speed performance of functions may be degraded due to processing of calls and returns. Therefore, macro functions should be used to improve speed performance. Note that if too many macro functions are used, the code is ex-panded in the places where each of them is used and the object size may increase. (See the Related rule.)

[Related rule] M5.1.3

Operations that remain unchanged shall not be per-formed within an iterated process.

E1.1.2

var1 = func();for (i = 0; (i + var1) < MAX; i++) { …}

/* Function func returns the same result */for (i = 0; (i + func()) < MAX; i++) { …}

Repeating the same process that returns the same result is inefficient. There are many cases where opti-mizations of the compiler can be relied on, but note the case when compliers do not recognize the invari-ance as shown in the example.

E1.1 Write with careful attention to resource and time ef-ficiencies.

Compliant example Non-compliant example

Compliant example Non-compliant example

Preference guide ●

Rule Specification

Preference guide ●

Rule Specification

126 Part2_Coding Practices for Embedded Software:Practices Chart

1

Efficiency

Instead of structures, pointers to structures shall be used as function parameters.

E1.1.3

typedef struct stag { int mem1; int mem2; …} STAG;int func (const STAG *p) { return p->mem1 + p->mem2; }

typedef struct stag { int mem1; int mem2; …} STAG;int func (STAG x) { return x.mem1 + x.mem2; }

If a structure is passed as a function argument, all the structure data are copied into the areas for the ar-gument upon the function call. If the size of the structure is large, it will be a cause of degrading speed performance. If a structure passed is read-only, not only pass it as a pointer to the structure, but also qualify it with const.

《Selection policy which to use switch statement or if statement shall be determined and defined in consideration of readability and efficiency.》

E1.1.4

switch statements often provide higher readability than if statements. In addition, recent compilers tend to output optimized code such as a table jump or binary search for switch statements. Take these into consideration when defining this rule.

Example of the rule:When a process branches according to the value of the expression (integer value), if the number of the branches is three or more, use a switch statement instead of if statements. However, if the use of the switch statement causes efficiency issues to improve the performance of the program, this rule does not apply to.

Compliant example Non-compliant example

Preference guide

Rule Specification

Preference guide

Rule Specification Define

Part3Typical Coding Errors

in Embedded Software

1 Meaningless expressions and statements

2 Wrong expressions and statements

3 Wrong memory usage

4 Errors due to misunderstandings in logical operations

5 Mistakes due to typos

6 Wrong descriptions that do not cause errors in some compilers

128 Part3 Typical Coding Errors in Embedded Software

Typical Coding Errors in Embedded Software

This section shows examples of coding errors that can be made by even skilled programmers as well as C language beginners. Some recent compilers provide enhanced warning functions as op-tions, and some of the examples here can be checked using compiler warnings or static analysis tools. However, by paying attention not to make such coding errors at the coding stage, the amount of work in later tasks can be reduced.

Some existing coding conventions include prevention of such coding errors as rules. It is recom-mended to examine whether to include them into the coding convention in consideration of the skill levels of those involved in the development.

This section explains the following six points along with examples.

・Meaningless expressions and statements

・Wrong expressions and statements

・Wrong memory usage

・Errors due to misunderstandings in logical operations

・Mistakes due to typos

・Wrong descriptions that do not cause errors in some compilers

1 Meaningless expressions and statements

Leaving statements or expressions that are not executed in the source code is likely to cause a misunderstanding, and in many cases, results in problems. It is said that confusion tends to be caused especially when a different engineer from the original programmer of the source code makes modifi-cations.

Example 1: Writing statements that are not executed.return ret;ret = ERROR;

This problem is caused either by putting a statement to branch the program control flow (return, continue, break, goto statement) into the wrong place, or forgetting to delete unnecessary state-ments when putting such a branch statement.

129Typical Coding Errors in Embedded Software

Example 2: Writing expressions that are not executedsize = sizeof(x++);

The expression in the ( ) of the sizeof operation is used only to calculate the size of the expres-sion type and is not executed.

If the ++ operator is written as in the example, the value will not be incremented.

Example 3: Writing statements whose execution result is not used.void func( ・・・ ) { int cnt; ・・・ cnt = 0; return;

Since automatic variables and formal parameters cannot be referenced after the function return, the update whose result value is not referenced between the update and the return statement becomes an unnecessary expression (statement). There is a possibility that some operation has been missed or unnecessary statements may be forgotten to be deleted during program modification.

Example 4: Writing expressions whose execution result is not used.int func( ・・・ ) { int cnt; ・・・ return cnt++;

The postfix ++ operation updates the value of the variable after it is referenced, so increments as in the example is meaningless. If you want to return the incremented value to the caller, the prefix increment should be used.

130 Part3 Typical Coding Errors in Embedded Software

Example 5: Values passed as arguments are not used.int func(int in) { in = 0; /* Overwriting the parameter */ ・・・}

As in the example, overwriting a parameter without referencing its value means that the value of the argument set by the caller is ignored. There is a possibility of a coding error.

2 Wrong expressions and statements

To write source code, it is necessary to follow the grammar of the programming language being used. Even a programmer familiar with the programming language can make careless mistakes. The following are examples of wrong expressions and statements often seen.

Example 1: Incorrect range specificationif (0 < x < 10)

The example program seems to be a correct description, but C language does not interpret such a description in a mathematical way. It is a conditional expression which is always true.

Example 2: Comparing outside the rangeunsigned char uc;unsigned int ui; ・・・if (uc == 256) ・・・switch (uc) {case 256: ・・・}if (ui < 0) ・・・

The variable is compared with a value beyond the range it can express. uc can only express values between 0 and 255. ui can never be negative.

131Typical Coding Errors in Embedded Software

Example 3: String comparisons cannot be performed with == operation.if (str == "abc")

The condition in the example compares addresses, and is not a condition whether the string “abc” is equal to the string pointed by str.

Example 4: Inconsistency between a function type and return statement of the function.

int func1(int in) { if (in < 0) return; /* Not good */ return in ;}int func2(void) { /* Not good */ ・・・ return;}

In the definition of a function that returns a value, all the return statements should describe the value to be returned in their expression (as function func1.) In addition, the type of a function that does not return a value should be void (as function func2.)

132 Part3 Typical Coding Errors in Embedded Software

3 Wrong memory usage

One characteristic of C language is that memory can be handled directly. While this is a very use-ful advantage when creating embedded software, its use often causes incorrect operations and should be used with care.

Example 1: Reference and update outside the array bounds.char var1[N];・・・for (i = 1; i <= N; i++) {/* Accessing outside the array bounds (Non-compliant) */ var1[i] = i;}var1[-1] = 0; /* NG */var1[N] = 0; /* NG */

The array index in C language starts with 0 and its maximum value is 1 less than the element count.

Example 2: Errors of passing the address of an automatic variable to the caller.int *func(tag *p) { int x; p->mem = &x; /* The automatic variable memory area is referenced after the function return (risky) */ return &x; /* The automatic variable memory area is referenced after the function return (risky) */}・・・ tag y; int *p; p = func(&y); *p = 10; /* Destroying invalid memory area */ *y.mem = 20; /* Destroying invalid memory area */

Areas for automatic variables or parameters are freed to the system when the function ends, and may be reused for other purposes. As in the example, if the address of an automatic variable is speci-fied as a function return value or set in an area that can be referenced by the caller, there is a risk of causing unexpected faults because such a reference or update is to the area that has been returned to the system.

133Typical Coding Errors in Embedded Software

Example 3: Referencing memory after being freed as dynamic memory.struct stag { /* A list structure */ struct stag *next; ...};struct stag *wkp; /* Pointer to the list structure */struct stag *top; /* Start pointer to the list structure */ .../* Process to free structures in the list structure one by one*//* Non-compliant as it accesses to the already freed area with the third control expression in the for statement after its free */for (wkp = top; wkp != NULL; wkp = wkp-> next) { free(wkp);}

Memories obtained by using malloc function need to be freed to the system using free func-tion. The areas that have been freed by free function will be reused by the system, and should not be referenced.

Example 4: Error of writing into string literalschar *s;s = "abc"; /* The area for the string literal may be ROM area */s[0] = 'A'; /* Cannot be written */

Depending on the compiler, string literals may be allocated in the const area. Programmers should be careful not to overwrite string literals.

Example 5: Error in specifying copy sizes#define A 10#define B 20char a[A];char b[B];・・・memcpy(a, b, sizeof(b));

When one array is copied to another, if the size of the source is used for the copy and is larger than that of the destination, it will corrupt the memory area. The best way to copy between arrays is to use arrays of the same size. Or, specifying the size of the copy to that of the destination at least prevent memory corruption.

134 Part3 Typical Coding Errors in Embedded Software

4 Errors due to misunderstandings in logical operations

Use of logical operators is error-prone. In situations where they are used, special care should be taken as there are many cases that subsequent processes are changed depending on the operation re-sults.

Example 1: Error of using a logical product instead of a logical sumif (x < 0 && x > 10)

The example shows a wrongly written logical product instead of a logical sum. Writing impos-sible conditions in C language does not cause compile errors, so caution should be required.

135Typical Coding Errors in Embedded Software

Example 2: Error of using a logical sum instead of a logical productint i, data[10], end = 0;for (i = 0; i < 10 || !end; i++) { data[i] = Value assigned; /* risk of corrupting outside the area */ if (termination condition) { end = 1; }}

To add another condition to the condition ensuring not to exceed the array bounds for an itera-tion statement that sequentially references or updates the array elements, these conditions should be specified with a logical product. The logical sum in the example possibility causes accessing outside the extent of the array.

Example 3: Error of using a bitwise operation instead of a logical operationif (len1 & len2)

This is an example of using a bitwise AND operator (&) where a logical product operator (&&) should be written. The bitwise AND operator does not mean to perform logical product of the condi-tions. The intention of the program should be correctly described.

5 Mistakes due to typos

Some operators in C language are taken for another such as = for == due to careless mistakes or typos, which completely changes the meaning. Sufficient attention should be paid to such mistakes.

Example 1: Write = operator instead of == operatorif (x = 0)

== should be written instead of = to check whether the values are equal. Rules to prevent such coding errors include “Assignment operators shall not be used in expressions to examine true or false.”

There are also cases of writing == operator instead of = operator such as a==b. Be careful of this as well.

136 Part3 Typical Coding Errors in Embedded Software

6 Wrong descriptions that do not cause errors in some ompilers

Each compiler has various characteristics of its own. Note that some compilers do not cause com-pile errors during compilation even if the program contains inappropriate descriptions.

Example 1: Multiple definitions of macros with the same name/* Depending on where AAA is referenced, what is expanded is different */#define AAA 100 a = AAA; /* 100 is assigned */#define AAA 10 b = AAA; /* 10 is assigned */

There are some compilers that do not cause a compile error if redefining a macro name with #de-fine without applying #undef for it beforehand. What is expanded is different depending on where the macro name is used will degrade readability.

Example 2: Error of writing into the const areavoid func(const int *p) { *p = 0; /* Writing into the const area (error) */

Some compilers do not cause a compile error even if the const area is rewritten. Programmers should be careful not to rewrite the const area.

Appendices

Appendix A List of practices and rules

Appendix B Rule classification based on C language grammar

Appendix C Documentation templates for implementation-defined items

138 Appendixes

Appendix A List of practices and rules

[Reliability 1] R1 Initialize areas and use them in consideration of their sizes.

Practices Rules Page

R1.1 Use areas after initializing them. R1.1.1 Automatic variables shall be initialized at the time of declaration or initial values shall be assigned just be-fore using them.

27

R1.1.2 const variables shall be initialized at the time of decla-ration.

27

R1.2 Describe initializations without excess or deficiency.

R1.2.1 Arrays with specified number of elements shall be initialized with values that match the number of the ele-ments.

28

R1.2.2 Initialization of enumerated type (enum type) members shall be one of the followings: not to specify constants at all, to specify all constants, or to specify the first member only.

28

R1.3 Pay attentions to the range pointed by a pointer.

R1.3.1 (1) Integer additions or subtractions (including ++, --) on pointers shall not be performed; Array format with [ ] shall be used for references and assignments to the allocated area.

(2) Integer additions or subtractions (including ++, --) on pointers shall be performed only when the pointer points to an array, and the result must reside within the range of the array.

29

R1.3.2 Subtractions between pointers shall only be used for those pointing to elements in the same array.

30

R1.3.3 Comparisons between pointers shall be applied only to pointers to elements in the same array or members of the same structure.

30

[Reliability 2] R2 Use data in consideration of their ranges, sizes and internal representations.

Practices Rules Page

R2.1 Make comparisons that do not de-pend on internal representations.

R2.1.1 Equality or inequality comparisons shall not be made for floating-point expressions.

32

R2.1.2 Floating-point variables shall not be used as loop coun-ters.

32

Appendix A List of practices and

139Appendix A _List of practices and rules

[Reliability 2] R2 Use data in consideration of their ranges, sizes and internal representations.

Practices Rules Page

R2.1 Make comparisons that do not de-pend on internal representations.

R2.1.3 memcmp shall not be used to compare structures and unions.

33

R2.2 Do not examine whether a value is equivalent to true value.

R2.2.1 Comparison with a value defined as true shall not be made in expressions that examine true or false.

33

R2.3 Use the same type to perform operations or make comparisons.

R2.3.1 Unsigned integer constant expressions shall be de-scribed within the range that can be represented with the result type.

34

R2.3.2 For a conditional operator (?: operator), the logical ex-pression shall be put in parenthese and the both return values shall be the same type.

34

R2.3.3 Loop counters and variables used for making com-parisons of loop iteration conditions shall be the same type.

35

R2.4 Describe code in consideration of operation precision.

R2.4.1 When the type of an operation and the type of the assignment destination of its result are different, the operation shall be performed after casting them to the type of the expected operation precision.

35

R2.4.2 When making arithmetic operations or comparisons mixed with signed and unsigned expressions, explicit casting shall be made into the expected type.

36

R2.5 Do not use operations that have a risk of information loss.

R2.5.1 When performing assignments (=operation, actual arguments passing of function calls, function return) or operations to data types that may cause informa-tion loss, check that there are not any problems. Casts shall be described to clearly indicate that there are no problems.

37

R2.5.2 Unary operator (‘-’) shall not be used in unsigned ex-pressions.

38

R2.5.3 When one’s complement (~) or left shift (<<) is applied to data with unsigned char type or unsigned short type, they shall be explicitly casted to the type of the result.

38

R2.5.4 The right-hand side of a shift operator shall be zero or more and less than the bit width of the left-hand side.

39

140 Appendixes

[Reliability 2] R2 Use data in consideration of their ranges, sizes and internal representations.

Practices Rules Page

R2.6 Use types with which the target data can be represented.

R2.6.1 The types used for bit field shall only be signed int and unsigned int. If a bit field of 1 bit width is required, not the signed int type but the unsigned int type shall be used.

40

R2.6.2 Data used as bit sequences shall be defined with unsigned type, not signed.

40

R2.7 Pay attention to the pointer types. R2.7.1 (1) Pointer types shall not be converted to other pointer types or integer types, the opposite conversions shall not be perfprmed either. However, conversion between the void* type and pointer types to data is the exception.

(2) Pointer types shall not be converted to other pointer types or int types with less data width than that of the pointer type. However, conversion between the void* type and pointer types to data is the exception.

(3) Pointer types to data can be converted to pointer types to other data types, but pointers to func-tion types shall not be converted to those to other function types or data types. When a pointer type is converted to an integral type, conversion to an inte-gral type with less data width than that of the pointer type shall not be performed.

41

R2.7.2 A cast shall not be performed that removes any const or volatile qualification from the type addressed by a pointer. [MISRA 11.5]

42

R2.7.3 Comparison that examines whether a pointer is nega-tive or not shall not be made.

42

R2.8 Write in the way that the compiler can check if there is no contradic-tion in declarations, usages and definitions.

R2.8.1 Functions with no parameters shall be declared with a void type parameter.

43

R2.8.2 (1) Functions shall not be defined with a variable num-ber of arguments.[MISRA 16.1]

(2) When using functions with a variable number of ar-guments,《document their behavior in the process-ing system》.

43

141Appendix A _List of practices and rules

[Reliability 2] R2 Use data in consideration of their ranges, sizes and internal representations.

Practices Rules Page

R2.8 Write in the way that the compiler can check if there is no contradic-tion in declarations, usages and definitions.

R2.8.3 A prototype declaration shall be made before function calls and its function definition. In addition, make sure that the same prototype declaration is referenced by their calls and its definition.

44

[Reliability 3] R3 Write in a way to ensure the behavior.

Practices Rules Page

R3.1 Write code in consideration of sizes of areas.

R3.1.1 (1) The number of elements in an extern declaration of an array shall be specified.

(2) The number of elements in an extern declaration of an array shall be specified except for that corre-sponding to an array definition with initialization that does not specify the number of elements.

46

R3.1.2 Iteration conditions for a loop to sequentially access array elements shall include a decision whether the access is within the range of the array.

47

R3.2 Avoid error cases for operations that may cause runtime errors.

R3.2.1 Operations shall be performed after checking that the right-hand side expression of division or remainder is not 0.

47

R3.2.2 Destination pointed by a pointer shall be referred to after checking that the pointer is not the null pointer.

48

R3.3 Check the interface restrictions for function calls.

R3.3.1 If a function returns error information, then that error information shall be tested. [MISRA 16.10]

48

R3.3.2 If there are constraints on parameters passed to a function, the function call shall be performed after checking the parameters are not beyond the limited values.

49

R3.4 Do not apply recursive calls. R3.4.1 Functions shall not call themselves, either directly or indirectly. [MISRA 16.2]

49

R3.5 Pay attention to branch conditions and describe handling processes in case those not stated occur.

R3.5.1 《Put an else clause at the end of an if-else if state-ment. If it is sure that the else condition does not normally occur, apply either one of the followings. (i) An exception handling process shall be written in the else clause. (ii) A comment specified by the project shall be written in the else clause. 》

50

142 Appendixes

[Reliability 4] R3 Write in a way to ensure the behavior.

Practices Rules Page

R3.5 Pay attention to branch conditions and describe handling processes in case those not stated occur.

R3.5.2 《Write the default clause at the end of a switch state-ment. If it is sure that the default condition does not normally occur, apply either one of the followings. (i) An exception handling process shall be written in the default clause. (ii) A comment specified by the project shall be written in the default clause.》

51

R3.5.3 Equality or inequality operators shall not be used for comparisons of loop counters. (<=, >=, <, or > shall be used.)

52

R3.6 Pay attention to the evaluation order.

R3.6.1 Variables whose values are changed in an expression shall not be referred to or modified in the same expres-sion.

53

R3.6.2 Function calls with side effects and volatile variables shall not be described more than once in a sequence of actual arguments or binary operation expressions.

54

[Maintainability1] M1 Consider that others will read the program

Practices Rules Page

M1.1 Do not leave unused descriptions. M1.1.1 Unused functions, variables, arguments or labels shall not be declared (defined.)

57

M1.1.2 Sections of code should not be “commented out.” [MISRA 2.4]

57

M1.2 Do not write in a misleading way. M1.2.1 (1) Only one variable shall be declared in one declara-tion statement (avoid multiple declarations.)

(2) Automatic variables of the same type used for the similar purposes may be declared in one declara-tion statement, but variables with initialization and variables without initialization shall not be mixed.

58

M1.2.2 Suffixes shall be added to constant descriptions that can use them to indicate appropriate types. Only an uppercase letter “L” shall be used for a suffix indicating a long type integer constant.

58

143Appendix A _List of practices and rules

[Maintainability1] M1 Consider that others will read the program

Practices Rules Page

M1.2 Do not write in a misleading way. M1.2.3 When expressing a long string literal, successive string literals shall be concatenated without using newlines within the string literal.

59

M1.3 Do not write in a specialized way. M1.3.1 Expressions to examine true or false result shall not be described in switch (expression).

60

M1.3.2 The case labels and the default label in a switch state-ment shall be described only in the compound state-ment (excluding nested compound statements) of the switch statement body.

60

M1.3.3 The types shall be explicitly described for definitions and declarations of functions and variables.

61

M1.4 Write in a way that operator pre-cedence is explicitly specified.

M1.4.1 The right-hand side and the left-hand side of && and || operations shall be described with simple variables or expressions enclosed by (). However, if && operations are successively combined or || operations are succes-sively combined, it is not necessary to enclose each && and || expression with ().

61

M1.4.2 《Usage of parentheses to explicitly indicate operator precedence shall be specified.》

62

M1.5 Do not omit operations that obtain function addresses or comparison operations.

M1.5.1 A function identifier (function name) shall only be used with either a preceding “&”, or with a parenthesized parameter list, which may be empty. [MISRA 16.9]

62

M1.5.2 Comparisons with 0 shall be explicitly written. 63

M1.6 Use one area for one purpose. M1.6.1 Variables shall be prepared for each purpose. 63

M1.6.2 (1) Unions shall not be used. [MISRA 18.4] (2) If unions are used, the same members that are as-

signed values shall be referenced.

64

144 Appendixes

[Maintainability1] M1 Consider that others will read the program

Practices Rules Page

M1.7 Do not reuse names. M1.7.1 The rules below shall be followed for name unique-ness.1. Identifiers in an inner scope shall not use the same

name as an identifier in an outer scope, and there-fore hide that identifier. [MISRA 5.2]

2. A typedef name shall be a unique identifier. [MISRA 5.3] 3. A tag name shall be a unique identifier. [MISRA 5.4] 4. No object or function identifier with static storage

duration should be reused. [MISRA 5.5] 5. No identifier in one namespace should have the

same spelling as an identifier in another namespace, with the exception of structure member and union member names. [MISRA 5.6]

65

M1.7.2 Names for functions, variables and macros in the standard library shall not be redefined or reused. In addition, those macro names shall not be undefined.

66

M1.7.3 Names (variables) that start with an underscore shall not be defined.

66

M1.8 Do not use language specifica-tions that can cause misunder-standing.

M1.8.1 The right-hand operand of a logical && or || operator shall not contain side effects. [MISRA 12.4]

67

M1.8.2 C macros shall only expand to a braced initializer, a constant, a parenthesised expression, a type qualifier, a storage class specifier, or a do-while-zero construct. [MISRA 19.4]

68

M1.8.3 #line shall not be used unless automatically generated by a tool.

68

M1.8.4 A sequence of three or more characters starting with ?? shall not be used.

69

M1.8.5 Octal constants (other than zero) and octal escape sequences shall not be used. [MISRA 7.1]

69

145Appendix A _List of practices and rules

[Maintainability1] M1 Consider that others will read the program

Practices Rules Page

M1.9 M1.9 Explicitly state the intention for a specialized way of writing.

M1.9.1 If statements that do nothing need to be intentionally described, comments or empty macros shall be used to make them noticeable.

70

M1.9.2 《A way of writing infinite loops shall be defined.》 70

M1.10 Do not embed magic numbers. M1.10.1 Meaningful constants shall be defined as macros be-fore their use.

71

M1.11 Explicitly state the attributes of areas.

M1.11.1 Read-only areas shall be declared as const. 71

M1.11.2 Memory spaces that might be updated by other execu-tion units shall be declared as volatile.

72

M1.11.3 《Rules for variable declaration and definition to ROMize shall be defined》

73

M1.12 Correctly describe statements even they are not compiled.

M1.12.1 Correct code shall be described even if it is to be de-leted by the preprocessor.

73

[Maintainability2] M2 Write in a way so as not to cause modification errors.

Practices Rules Page

M2.1 Clarify the grouping of structured data and blocks.

M2.1.1 If arrays and structures are initialized with values other than 0, their forms of structure shall be indicated using braces ‘{ }’ according to the forms. Data shall be de-scribed without any omissions, except when all values are 0.

75

M2.1.2 The body of if, else if, else, while, do, for, and switch statements shall be made into blocks.

75

M2.2 Localize access ranges and related data.

M2.2.1 Variables used only in one function shall be declared within the function.

76

M2.2.2 Variables accessed by several functions defined in the same file shall be declared with static in the file scope.

77

M2.2.3 Functions that are called only by functions defined in the same file shall be as static.

77

M2.2.4 enum shall be used rather than #define when defining related constants.

78

146 Appendixes

[Maintainability3] M3 Write program in a simple way.

Practices Rules Page

M3.1 Do structured programming. M3.1.1 For any iteration statement, there shall be at most one break statement used for loop termination. [MISRA 14.6]

80

M3.1.2 (1) The goto statement shall not be used.(2) The goto statement shall be used only when exiting

multiple loops or when jumping to error handling.

81

M3.1.3 The continue statement shall not be used. [MISRA 14.5]

81

M3.1.4 (1) Always end the case clauses and the default clause in a switch statement with a break statement.

(2) When an case clause and the default clause in a switch statement is not ended with a break state-ment, 《define a comment in your project》 and insert that comment.

82

M3.1.5 (1) Functions shall end with one return statement. (2) Return statements in the middle of a process shall

be only the cases for abnormal return.

83

M3.2 One statement should have one side effect.

M3.2.1 (1) Comma expressions shall not be used. (2) Comma expressions shall only be used in initial-

ization expressions and update expressions of for statements.

83

M3.2.2 Multiple assignments shall not be described in one statement, except when the same value is assigned to multiple variables.

84

M3.3 Separately describe expressions with different purposes.

M3.3.1 The three expressions of a for statement shall be con-cerned only with loop control. [MISRA 13.5]

84

M3.3.2 Numeric variables being used within a for loop for itera-tion counting shall not be modified in the body of the loop.[MISRA 13.6]

85

147Appendix A _List of practices and rules

[Maintainability3] M3 Write program in a simple way.

Practices Rules Page

M3.3 Separately describe expressions with different purposes.

M3.3.3 (1) Assignment operators shall not be used in expres-sions to examine true or false.

(2) Assignment operators shall not be used in expres-sions to examine true or false, except for conven-tionally used notations.

85

M3.4 Do not use complicated pointer operations.

M3.4.1 Pointer references of three or more levels shall not be used.

86

[Maintainability4] M4 Write in a unified style.

Practices Rules Page

M4.1 Unify coding styles. M4.1.1 《Conventions regarding styles such as braces ({), indentation or how to insert spaces shall be defined.》

88

M4.2 Unify how to write comments. M4.2.1 《Conventions regarding how to write file header comments, function header comments, end of line comments, block comments and copyright shall be defined.》

91

M4.3 Unify how to name. M4.3.1 《Conventions for naming external variables and inter-nal variables shall be defined.》

93

M4.3.2 《Conventions for naming files shall be defined.》 93

M4.4 Unify description contents and their order in files.

M4.4.1 《The contents (declarations, definitions, etc.) described in header files and their order shall be defined.》

95

M4.4.2 《The contents (declarations, definitions, etc.) described in source files and their order shall be defined.》

96

M4.4.3 To use or define external variables or functions (except for functions used only in the file), the header file de-scribing their declarations shall be included.

97

M4.4.4 External variables shall not be defined in multiple loca-tions.

97

M4.4.5 Variable definitions or function definitions shall not be described in a header file.

98

148 Appendixes

[Maintainability4] M4 Write in a unified style.

Practices Rules Page

M4.4 Unify description contents and their order in files.

M4.4.6 Header files shall be written so as to handle redundant inclusions.《A way of writing to achieve this shall be defined.》

98

M4.5 Unify how to write declarations. M4.5.1 (1) In a function prototype declaration, all the param-eters shall not be named (types only.)

(2) In a function prototype declaration, all the param-eters shall be named. In addition, the types of the parameters, their names and the type of the return value shall be literally the same as those of the function definition.

99

M4.5.2 Structure tags and variables shall be declared sepa-rately.

100

M4.5.3 (1) “,” shall not be put before the last “}” in the list of initial value expressions for structures, unions and arrays, nor in the list of enumerators.

(2)“,” shall not be put before the last “}” in the list of initial value expressions for structures, unions and arrays, nor in the list of enumerators. However, to put “,” before the last “}” in the list of initial values for array initialization is allowed.

100

M4.6 Unify how to write the null pointer. M4.6.1 (1) 0 shall be used for the null pointer. NULL shall not be used in any case.

(2) NULL shall be used for the null pointer. NULL shall not be used for anything other than the null pointer.

101

M4.7 Unify how to write preprocessing directives.

M4.7.1 The body and the parameters of a macro that has operators shall be enclosed with parentheses.

102

M4.7.2 #else or #endif that corresponds to #ifdef, #ifndef and #if shall be described in the same file and their cor-respondence shall be clearly stated with a comment

《defined in the project.》

102

M4.7.3 “defined (macro name)” shall be used to check whether a macro name has already been defined by #if. Writing “#if macro name” shall not be used.

103

149Appendix A _List of practices and rules

[Maintainability4] M4 Write in a unified style.

Practices Rules Page

M4.7 Unify how to write preprocessing directives.

M4.7.4 defined operator used in #if and #elif shall be written as “defined (macro name)” or “defined macro name”, and not in any other way.

103

M4.7.5 Macros shall not be #define’d or #undef’d within a block. [MISRA 19.5]

104

M4.7.6 #undef shall not be used. [MISRA 19.6] 104

[Maintainability5] M5 Write in a way easy to test.

Practices Rules Page

M5.1 Write in a way that is easy to investigate the cause of problems.

M5.1.1 《A way of coding for setting debug options and writing logs in release modules shall be defined.》

106

M5.1.2 (1) The # and ## preprocessor operators should not be used. [MISRA 19.13]

(2) There shall be at most one occurrence of the # or ## preprocessor operators in a single macro defini-tion.[MISRA 19.12]

108

M5.1.3 Functions shall be used rather than function-like mac-ros.

109

M5.2 Be careful when using dynamic memory allocations.

M5.2.1 (1) Dynamic memories shall not be used.(2) If dynamic memories are used, 《the maximum used

memories, processes in case of insufficient memo-ries, and debugging procedures shall be defined.》

109

[Portability 1] P1 Write in a compiler independent way.

Practices Rules Page

P1.1 Do not use advanced function-alities or implementation-defined functionalities.

P1.1.1 (1) Functionalities not specified in the C90 standard shall not be used.

(2) If functionalities not specified in the C90 standard are used, 《document the functionalities to be used and their usage.》

113

P1.1.2 《All usage of implementation-defined behavior shall be documented.》 [MISRA 3.1]

113

P1.1.3 To use a program written in another language, 《its interface shall be documented and its usage shall be defined.》

114

150 Appendixes

[Portability 1] P1 Write in a compiler independent way.

Practices Rules Page

P1.2 Use only characters and escape sequences defined in the lan-guage standard.

P1.2.1 To use characters other than those defined in C90 for writing a program, the compiler specifications shall be confirmed 《and their usage shall be defined.》

114

P1.2.2 Only escape sequences defined in the language stan-dard shall be used.

115

P1.3 Confirm and document repre-sentation for data types, behav-ioral specifications of advanced functionalities and implementation-dependent parts.

P1.3.1 Simple char type (signed or unsigned not specified) shall be used only for (processes of) storing character values. If a process that depends on signed or un-signed (implementation-defined) is required, unsigned char or signed char specifying its sign shall be used.

116

P1.3.2 The members of an enumeration type (enum) shall be defined with values that can be represented as int type.

116

P1.3.3 (1) Bit fields shall not be used. (2) Bit fields shall not be used for data whose bit posi-

tions are meaningful. (3)《If it is being relied upon, the implementation-

defined behavior and packing of bit fields shall be documented.》 [MISRA 3.5]

117

P1.4 Confirm implementation-depen-dent parts for source file inclu-sion, and write implementation-independent inclusions.

P1.4.1 The #include directive shall be followed by either a <file-name> or “filename” sequence. [MISRA 19.3]

118

P1.4.2 《The usage of <> format and “” format for #include file specification shall be defined.》

118

P1.4.3 Characters ‘, \, “, /*, and : shall not be used for the file specification in #include.

119

P1.5 Write in a way that does not de-pend on the compilation environ-ment.

P1.5.1 The absolute path shall not be written for the file speci-fication in #include.

119

151Appendix A _List of practices and rules

[Portability 2] P2 Localize code that has portability problems.

Practices Rules Page

P2.1 P2.1 Localize code that has porta-bility problems.

P2.1.1 When assembly language programs are called from C language, 《how to localize such parts shall be defined》 by, for example, expressing them as functions of C language that contain only inline assembly language code or describing them using macros.

121

P2.1.2 Extended keywords provided by the processing system shall be localized to use《by defining macros》

121

P2.1.3 (1) The basic types such as char, int, long, float, and double shall not be used. Instead, types defined by typedef shall be used. 《The types defined by typedef to be used in the project shall be defined.》

(2) If the basic types such as char, int, long, float, and double are used in a form that depends on their sizes, types defined by typedef for each of the basic types shall be used. 《The types defined by typedef to be used in the project shall be defined.》

122

[Efficiency1] E1 Write with careful attention to resource and time efficiencies.

Practices Rules Page

E1.1 Write with careful attention to resource and time efficiencies.

E1.1.1 Macro functions shall be used only in parts related to speed performance.

125

E1.1.2 Operations that remain unchanged shall not be per-formed within an iterated process.

125

E1.1.3 Instead of structures, pointers to structures shall be used as function parameters.

126

E1.1.4 《Selection policy which to use switch statement or if statement shall be determined and defined in consider-ation of readability and efficiency.》

126

152 Appendixes

Appendix B Rule classification based on the C language grammar

The rules are classified according to the C language grammar shown below.

Classification based on the grammar No. Rule

1. Style

1.1 Syntax style M4.1.1 《Conventions regarding styles such as braces ({), indentation or how to insert spaces shall be defined.》

1.2 Comments M4.2.1 《Conventions regarding how to write file header comments, function header comments, end of line comments, block comments and copyright shall be defined.》

1.3 Naming M4.3.1 《Conventions for naming external variables and internal variables shall be defined.》

M4.3.2 《Conventions for naming files shall be defined.d.》

M1.7.1 The rules below shall be followed for name uniqueness.1. Identifiers in an inner scope shall not use the same name as an identifier in

an outer scope, and therefore hide that identifier. [MISRA 5.2] 2. A typedef name shall be a unique identifier. [MISRA 5.3] 3. A tag name shall be a unique identifier. [MISRA 5.4] 4. No object or function identifier with static storage duration should be reused.

[MISRA 5.5] 5. No identifier in one namespace should have the same spelling as an identi-

fier in another namespace, with the exception of structure member and union member names. [MISRA 5.6]

M1.7.2 Names for functions, variables and macros in the standard library shall not be redefined or reused. In addition, those macro names shall not be undefined.

M1.7.3 Names (variables) that start with an underscore shall not be defined.

1.4 Composition of a file M4.4.1 《The contents (declarations, definitions, etc.) described in header files and their order shall be defined.》

M4.4.5 Variable definitions or function definitions shall not be described in a header file.

Appendix B Rule classification based on the C language grammar

153Appendix B _Rule classification based on C language grammar

Classification based on the grammar No. Rule

1. Style

1.4 Composition of a file M4.4.6 Header files shall be written so as to handle redundant inclusions.《A way of writing to achieve this shall be defined.》

M4.4.2 《The contents (declarations, definitions, etc.) described in source files and their order shall be defined.》

M4.4.3 To use or define external variables or functions (except for functions used only in the file), the header file describing their declarations shall be included.

1.5 Constants M1.2.2 Suffixes shall be added to constant descriptions that can use them to indicate appropriate types. Only an uppercase letter “L” shall be used for a suffix indi-cating a long type integer constant.

M1.8.5 Octal constants (other than zero) and octal escape sequences shall not be used. [MISRA 7.1]

M1.2.3 When expressing a long string literal, successive string literals shall be concat-enated without using newlines within the string literal.

M1.10.1 Meaningful constants shall be defined as macros before their use.

1.6 Other (Style) M1.1.2 Sections of code should not be “commented out.” [MISRA 2.4]

M1.9.1 If statements that do nothing need to be intentionally described, comments or empty macros shall be used to make them noticeable.

M1.8.4 A sequence of three or more characters starting with ?? shall not be used.

M5.1.3 Functions shall be used rather than function-like macros.

2. Type

2.1 Basic types P2.1.3 (1) The basic types such as char, int, long, float, and double shall not be used. Instead, types defined by typedef shall be used. 《The types defined by typedef to be used in the project shall be defined.》

(2) If the basic types such as char, int, long, float, and double are used in a form that depends on their sizes, types defined by typedef for each of the basic types shall be used. 《The types defined by typedef to be used in the project shall be defined.》

154 Appendixes

Classification based on the grammar No. Rule

2. Type

2.1 Basic types P1.3.1 Simple char type (signed or unsigned not specified) shall be used only for (processes of) storing character values. If a process that depends on signed or unsigned (implementation-defined) is required, unsigned char or signed char specifying its sign shall be used.

R2.6.2 Data used as bit sequences shall be defined with unsigned type, not signed.

2.2 Structures/Unions M4.5.2 Structure tags and variables shall be declared separately.

M1.6.2 (1) Unions shall not be used. [MISRA 18.4] (2) If unions are used, the same members that are assigned values shall be

referenced.

R2.1.3 memcmp shall not be used to compare structures and unions.

2.3 Bit fields P1.3.3 (1) Bit fields shall not be used. (2) Bit fields shall not be used for data whose bit positions are meaningful. (3)《If it is being relied upon, the implementation-defined behavior and packing

of bit fields shall be documented.》 [MISRA 3.5]

R2.6.1 The types used for bit field shall only be signed int and unsigned int. If a bit field of 1 bit width is required, not the signed int type but the unsigned int type shall be used.

2.4 Enumerated type R1.2.2 Initialization of enumerated type (enum type) members shall be one of the followings: not to specify constants at all, to specify all constants, or to specify the first member only.

M2.2.4 enum shall be used rather than #define when defining related constants.

P1.3.2 The members of an enumeration type (enum) shall be defined with values that can be represented as int type.

3. Declaration/Definition

3.1 Initialization R1.1.1 Automatic variables shall be initialized at the time of declaration or initial values shall be assigned just before using them.

R1.1.2 const variables shall be initialized at the time of declaration.

R1.2.1 Arrays with specified number of elements shall be initialized with values that match the number of the elements.

155Appendix B _Rule classification based on C language grammar

Classification based on the grammar No. Rule

3. Declaration/Definition

3.1 Initialization M2.1.1 If arrays and structures are initialized with values other than 0, their forms of structure shall be indicated using braces ‘{ }’ according to the forms. Data shall be described without any omissions, except when all values are 0.

M4.5.3 (1) “,” shall not be put before the last “}” in the list of initial value expressions for structures, unions and arrays, nor in the list of enumerators.

(2)“,” shall not be put before the last “}” in the list of initial value expressions for structures, unions and arrays, nor in the list of enumerators. However, to put “,” before the last “}” in the list of initial values for array initialization is allowed.

3.2 Variable declaration/definition

M1.2.1 (1) Only one variable shall be declared in one declaration statement (avoid multiple declarations.)

(2) Automatic variables of the same type used for the similar purposes may be declared in one declaration statement, but variables with initialization and variables without initialization shall not be mixed.

M1.11.1 Read-only areas shall be declared as const.

M1.11.2 Memory spaces that might be updated by other execution units shall be de-clared as volatile.

M2.2.1 Variables used only in one function shall be declared within the function.

M2.2.2 Variables accessed by several functions defined in the same file shall be de-clared with static in the file scope.

M4.4.4 External variables shall not be defined in multiple locations.

M1.6.1 Variables shall be prepared for each purpose.

M1.11.3 《Rules for variable declaration and definition to ROMize shall be defined》

3.3 Function declaration/definition

R2.8.3 A prototype declaration shall be made before function calls and its function definition. In addition, make sure that the same prototype declaration is refer-enced by their calls and its definition.

156 Appendixes

Classification based on the grammar No. Rule

3. Declaration/Definition

3.3 Function declaration/definition

M4.5.1 (1) In a function prototype declaration, all the parameters shall not be named (types only.)

(2) In a function prototype declaration, all the parameters shall be named. In addition, the types of the parameters, their names and the type of the return value shall be literally the same as those of the function definition.

R2.8.1 Functions with no parameters shall be declared with a void type parameter.

R2.8.2 (1) Functions shall not be defined with a variable number of arguments. [MISRA 16.1] (2) When using functions with a variable number of arguments,《document their

behavior in the processing system》.

M2.2.3 Functions that are called only by functions defined in the same file shall be as static.

3.4 Array declaration/definition

R3.1.1 (1) The number of elements in an extern declaration of an array shall be speci-fied.

(2) The number of elements in an extern declaration of an array shall be speci-fied except for that corresponding to an array definition with initialization that does not specify the number of elements.

3.5 Other (declaration/definition)

M1.1.1 Unused functions, variables, arguments or labels shall not be declared (de-fined.)

M1.3.3 The types shall be explicitly described for definitions and declarations of func-tions and variables.

4. Expression

4.1 Function call R3.3.2 If there are constraints on parameters passed to a function, the function call shall be performed after checking the parameters are not beyond the limited values.

R3.3.1 If a function returns error information, then that error information shall be tested. [MISRA 16.10]

R3.4.1 Functions shall not call themselves, either directly or indirectly. [MISRA 16.2]

157Appendix B _Rule classification based on C language grammar

Classification based on the grammar No. Rule

4. Expression

4.2 Pointer R2.7.1 (1) Pointer types shall not be converted to other pointer types or integer types, the opposite conversions shall not be perfprmed either. However, conversion between the void* type and pointer types to data is the exception.

(2) Pointer types shall not be converted to other pointer types or int types with less data width than that of the pointer type. However, conversion between the void* type and pointer types to data is the exception.

(3) Pointer types to data can be converted to pointer types to other data types, but pointers to function types shall not be converted to those to other func-tion types or data types. When a pointer type is converted to an integral type, conversion to an integral type with less data width than that of the pointer type shall not be performed.

R1.3.1 (1) Integer additions or subtractions (including ++, --) on pointers shall not be per-formed; Array format with [ ] shall be used for references and assignments to the allocated area.

(2) Integer additions or subtractions (including ++, --) on pointers shall be per-formed only when the pointer points to an array, and the result must reside within the range of the array.

R1.3.2 Subtractions between pointers shall only be used for those pointing to ele-ments in the same array.

R1.3.3 Comparisons between pointers shall be applied only to pointers to elements in the same array or members of the same structure.

R2.7.3 Comparison that examines whether a pointer is negative or not shall not be made.

R3.2.2 Destination pointed by a pointer shall be referred to after checking that the pointer is not the null pointer.

M3.4.1 Pointer references of three or more levels shall not be used.

M4.6.1 (1) 0 shall be used for the null pointer. NULL shall not be used in any case. (2) NULL shall be used for the null pointer. NULL shall not be used for anything

other than the null pointer.

4.3 Cast R2.4.2 When making arithmetic operations or comparisons mixed with signed and unsigned expressions, explicit casting shall be made into the expected type.

R2.7.2 A cast shall not be performed that removes any const or volatile qualification from the type addressed by a pointer. [MISRA 11.5]

158 Appendixes

Classification based on the grammar No. Rule

4. Expression

4.4 Unary operation R2.5.2 Unary operator (‘-’) shall not be used in unsigned expressions.

M1.5.1 A function identifier (function name) shall only be used with either a preceding “&”, or with a parenthesized parameter list, which may be empty. [MISRA 16.9]

4.5 The four arithmetic operations

R3.2.1 Operations shall be performed after checking that the right-hand side expres-sion of division or remainder is not 0.

4.6 Shift R2.5.4 The right-hand side of a shift operator shall be zero or more and less than the bit width of the left-hand side.

4.7 Comparison R2.1.1 Equality or inequality comparisons shall not be made for floating-point expres-sions.

R2.2.1 Comparison with a value defined as true shall not be made in expressions that examine true or false.

M1.5.2 Comparisons with 0 shall be explicitly written.

4.8 Bit operation R2.5.3 When one’s complement (~) or left shift (<<) is applied to data with unsigned char type or unsigned short type, they shall be explicitly casted to the type of the result.

4.9 Logical operation M1.4.1 The right-hand side and the left-hand side of && and || operations shall be described with simple variables or expressions enclosed by (). However, if && operations are successively combined or || operations are successively combined, it is not necessary to enclose each && and || expression with ().

M1.8.1 The right-hand operand of a logical && or || operator shall not contain side ef-fects. [MISRA 12.4]

4.10 Ternary operation R2.3.2 For a conditional operator (?: operator), the logical expression shall be put in parenthese and the both return values shall be the same type.

4.11 Assignment R2.5.1 When performing assignments (=operation, actual arguments passing of func-tion calls, function return) or operations to data types that may cause informa-tion loss, check that there are not any problems. Casts shall be described to clearly indicate that there are no problems.

R2.4.1 When the type of an operation and the type of the assignment destination of its result are different, the operation shall be performed after casting them to the type of the expected operation precision.

159Appendix B _Rule classification based on C language grammar

Classification based on the grammar No. Rule

4. Expression

4.11 Assignment M3.3.3 (1) Assignment operators shall not be used in expressions to examine true or false.

(2) Assignment operators shall not be used in expressions to examine true or false, except for conventionally used notations.

4.12 Comma M3.2.1 (1) Comma expressions shall not be used. (2) Comma expressions shall only be used in initialization expressions and

update expressions of for statements.

4.13 Priority and Side effect

R3.6.1 Variables whose values are changed in an expression shall not be referred to or modified in the same expression.

R3.6.2 Function calls with side effects and volatile variables shall not be described more than once in a sequence of actual arguments or binary operation expres-sions.

M1.4.2 《Usage of parentheses to explicitly indicate operator precedence shall be specified.》

4.14 Other (Expression) R2.3.1 Unsigned integer constant expressions shall be described within the range that can be represented with the result type.

5. Statement

5.1 if statement R3.5.1 《Put an else clause at the end of an if-else if statement. If it is sure that the else condition does not normally occur, apply either one of the followings. (i) An exception handling process shall be written in the else clause. (ii) A comment specified by the project shall be written in the else clause. 》

5.2 switch statement M3.1.4 (1) Always end the case clauses and the default clause in a switch statement with a break statement.

(2) When an case clause and the default clause in a switch statement is not ended with a break statement, 《define a comment in your project》 and insert that comment.

R3.5.2 《Write the default clause at the end of a switch statement. If it is sure that the default condition does not normally occur, apply either one of the followings. (i) An exception handling process shall be written in the default clause. (ii) A comment specified by the project shall be written in the default clause.》

160 Appendixes

Classification based on the grammar No. Rule

5. Statement

5.2 switch statement M1.3.1 Expressions to examine true or false result shall not be described in switch (expression).

M1.3.2 The case labels and the default label in a switch statement shall be described only in the compound statement (excluding nested compound statements) of the switch statement body.

5.3 for/while statement R2.1.2 Floating-point variables shall not be used as loop counters.

R2.3.3 Loop counters and variables used for making comparisons of loop iteration conditions shall be the same type.

R3.5.3 Equality or inequality operators shall not be used for comparisons of loop counters. (<=, >=, <, or > shall be used.)

M3.3.1 The three expressions of a for statement shall be concerned only with loop control. [MISRA 13.5]

M3.3.2 Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.[MISRA 13.6]

M3.1.1 For any iteration statement, there shall be at most one break statement used for loop termination. [MISRA 14.6]

M3.1.3 The continue statement shall not be used. [MISRA 14.5]

R3.1.2 Iteration conditions for a loop to sequentially access array elements shall include a decision whether the access is within the range of the array.

M1.9.2 《A way of writing infinite loops shall be defined.》

5.4 Other (statement) M2.1.2 The body of if, else if, else, while, do, for, and switch statements shall be made into blocks.

M3.1.2 (1) The goto statement shall not be used.(2) The goto statement shall be used only when exiting multiple loops or when

jumping to error handling.

M3.1.5 (1) Functions shall end with one return statement. (2) Return statements in the middle of a process shall be only the cases for

abnormal return.

161Appendix B _Rule classification based on C language grammar

Classification based on the grammar No. Rule

5. Statement

5.4 Other (statement) M3.2.2 Multiple assignments shall not be described in one statement, except when the same value is assigned to multiple variables.

6. Macro/preprocessor

6.1 #if related M4.7.2 #else or #endif that corresponds to #ifdef, #ifndef and #if shall be described in the same file and their correspondence shall be clearly stated with a comment

《defined in the project.》

M4.7.3 “defined (macro name)” shall be used to check whether a macro name has already been defined by #if. Writing “#if macro name” shall not be used.

M4.7.4 defined operator used in #if and #elif shall be written as “defined (macro name)” or “defined macro name”, and not in any other way.

6.2 #include P1.4.1 The #include directive shall be followed by either a <filename> or “filename” sequence. [MISRA 19.3]

P1.4.2 《The usage of <> format and “” format for #include file specification shall be defined.》

P1.4.3 Characters ‘, \, “, /*, and : shall not be used for the file specification in #include.

P1.5.1 The absolute path shall not be written for the file specification in #include.

6.3 Macro M4.7.1 The body and the parameters of a macro that has operators shall be enclosed with parentheses.

M1.8.2 C macros shall only expand to a braced initializer, a constant, a parenthesised expression, a type qualifier, a storage class specifier, or a do-while-zero con-struct. [MISRA 19.4]

M4.7.5 Macros shall not be #define’d or #undef’d within a block. [MISRA 19.5]

M4.7.6 #undef shall not be used. [MISRA 19.6]

6.4 Other (preprocessor) M1.12.1 Correct code shall be described even if it is to be deleted by the preprocessor.

M1.8.3 #line shall not be used unless automatically generated by a tool.

162 Appendixes

Classification based on the grammar No. Rule

6. Macro/preprocessor

6.4 Other (preprocessor) M5.1.2 (1) The # and ## preprocessor operators should not be used. [MISRA 19.13] (2) There shall be at most one occurrence of the # or ## preprocessor opera-

tors in a single macro definition.[MISRA 19.12]

7. Environment/Other

7.1 Portability P1.1.1 (1) Functionalities not specified in the C90 standard shall not be used. (2) If functionalities not specified in the C90 standard are used, 《document the

functionalities to be used and their usage.》

P1.1.2 《All usage of implementation-defined behavior shall be documented.》 [MISRA 3.1]

P1.2.1 To use characters other than those defined in C90 for writing a program, the compiler specifications shall be confirmed 《and their usage shall be defined.》

P1.2.2 Only escape sequences defined in the language standard shall be used.

P1.1.3 To use a program written in another language, 《its interface shall be docu-mented and its usage shall be defined.》

P2.1.1 When assembly language programs are called from C language, 《how to localize such parts shall be defined》 by, for example, expressing them as functions of C language that contain only inline assembly language code or describing them using macros.

P2.1.2 Extended keywords provided by the processing system shall be localized to use《by defining macros》

7.2 Performance E1.1.1 Macro functions shall be used only in parts related to speed performance.

E1.1.2 Operations that remain unchanged shall not be performed within an iterated process.

E1.1.3 Instead of structures, pointers to structures shall be used as function param-eters.

E1.1.4 《Selection policy which to use switch statement or if statement shall be deter-mined and defined in consideration of readability and efficiency.》

7.3 Description for de-bug

M5.1.1 《A way of coding for setting debug options and writing logs in release modules shall be defined.》

163Appendix B _Rule classification based on C language grammar

Classification based on the grammar No. Rule

7. Environment/Other

7.4 Other M5.2.1 (1) Dynamic memories shall not be used.(2) If dynamic memories are used, 《the maximum used memories, processes

in case of insufficient memories, and debugging procedures shall be de-fined.》

164 Appendixes

Appendix C Documentation templates for implementation-defined items

To use implementation-defined functionalities, items specifications of the processing system selected shall be documented. The following table is a template for documentation.

Processing system name

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

1 Diagnostic messages

Identification of diagnostics. (5.1.1.3)

P1.1.2 In many cases, de-scription is not nec-essary. (There is no problem)

2 Program startup

Semantics of arguments to main. (5.1.2.2.1)

P1.1.2 Use parameters of the main function

3 Interactive devices

What constitutes an interactive device. (5.1.2.3)

P1.1.2 In many cases, de-scription is not neces-sary.

Appendix C Documentation templates for implementation-defined items

165Appendix C _Documentation templates for implementation-defined items

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

4 Name identi-fication

(31 or more) significant initial characters for an identifier not with external linkage. (6.1.2)

P1.1.2 Name with 32 charac-ters or more.(In C90 standard, an external identifier needs to be identified by up to 5 characters. However, there might be no compilers that do not support 31 characters in recent systems. Further-more, in C99 at last 31 initial characters are significant even in an external identifier. Thus, behavior check of processing system is mandatory only for external identifiers with 32 characters or more.)

( )characters

5 (6 or more) significant initial characters for an identifier with external linkage. (6.1.2)

P1.1.2 ( )characters

6 Whether there are case distinc-tions between identifiers with external linkage. (6.1.2)

P1.1.2 Required. (Pay atten-tion to the distinction between uppercase and lowercase letters in the naming conven-tion.)For reference: In C99, standard, lowercase and uppercase letters are distinct.

□ Distinct□ Not distinct

166 Appendixes

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

7 Source and execution character set

Elements of source and execu-tion character sets other than those explicitly defined in the standard.(5.2.1)

P1.2.1 Using characters other than members of the basic source character set or the basic execu-tion character set.Note: The basic source character set consists of the 26 uppercase letters and the 26 low-ercase letters of the Latin alphabet, the 10 decimal digits, the 29 graphic characters (!, “ etc.), the space character, and control characters represent-ing horizontal tab, vertical tab, and form feed. The basic execution character set consists of the basic source character set, the null character, and the 4 control characters representing alert, backspace, carriage return, and new-line. This item applies to write comments in Japanese.

Example:Source characters: Japanese characters, SJIS encoding.Execution characters: Japanese characters, EUC encoding.

8 Shift states used for encoding multibyte characters (5.2.1.2)

P1.1.2 Not necessary if the characters used (the execution character set) are specified in 7 above.

167Appendix C _Documentation templates for implementation-defined items

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

9 Source and execution character set

Number of bits for characters in the execution character set (5.2.4.2.1)

P1.1.2 Mostly 8bits. Describe if 16bits.

□ 8bits□ 16bits□ Other (     )

10 Correspondence between ele-ments of the source character set and those of the execution character set (in character con-stants and string literals) (6.1.3.4)

P1.1.2 Mostly explained in 7. Describe if there are special cases.

11 The value of an integer character constant containing a character that does not be represented with the execution character set or an escape sequence. For wide character constants, the value of a wide character con-stant containing a character that does not be represented with the extended character set or an escape sequence. (6.1.3.4)

P1.1.2 Using any of the fol-lowing.

・Characters that can-not be represented with the basic execu-tion character set.

・Integer character constants containing an escape sequence

・Wide character con-stants -Characters that cannot be repre-sented with the extended character set.

-Escape sequencesNote:The definition needs to be made only the parts to use.

・Character that can-not be represented with the basic execu-tion character set.

・Integer character constants containing an escape sequence.

・Wide character con-stants -Characters that cannot be repre-sented with the extended charac-ter set.

-Escape sequenc-es

168 Appendixes

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

12 Source and execution character set

The value of an integer character constant containing more than one character or the value of a wide character constant con-taining more than one multibyte character.

P1.1.2 Using character con-stants contacting more than one character. Example: ‘ab’ ‘漢 ’ L’ab’

・The value of integer character constants containing more than one character.

・The value of wide character constants containing more than one multibyte character.

13 Locale used for converting a multibyte character to a corre-sponding wide character (code) for wide character constants. (6.1.3.4)

P1.1.2 Using multibyte char-acters.

14 Range of data types

Which of signed char or unsigned char has the same range as “plain” char (without sign specifi-cation.) (6.2.1.1)

P1.1.2 Using plain char. □ The same as signed char

□ The same as un-signed char

15 Representation and set of values for various integer types. (6.2.1.5)

P2.1.3 Required. Described later (1)

169Appendix C _Documentation templates for implementation-defined items

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

16 Range of data types

Conversion result in which the value cannot be represented when an integer is converted to a shorter signed integer or when an unsigned integer is converted to a signed integer of the same size. (6.2.1.2)

P1.1.2 Converting to shorter signed types or con-vert to a signed type from an unsigned type of the same size.

Converting to a shorter signed type.□ Bit sequence image

remains the same (The leading bits are discarded.)

□ Other (     )Converting an unsigned type to a signed type.

□ Bit sequence image remains the same

□ Other (     )

17 Operation result

The result of bitwise operations (~, <<, >>, &, ^, |) on signed integers. (6.3)

R2.6.2 Applying bitwise oper-ations (~, <<, >>, &, ^, |) for signed integers.

Described later (2)

18 The sign of the remainder on integer division (6.3.5)

P1.1.2 Applying division (/) or remainder (%) on negative values (C99 defines that the result of the division is trun-cation toward zero and is not implementation-dependent).

□ The same sign as the dividend (the result of the division is truncated toward zero)

□ The same sign as the divisor

□ Other (     )

19 The result of a right shift of a negative-valued signed integral type (6.3.7)

R2.5.4 Applying a right shift to a negative-valued signed integral type.

20 Floating- point

The representation and sets of values of the various types of floating-point numbers.(6.1.2.5)

R2.1.1R2.1.2

Using floating-points.

170 Appendixes

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

21 Floating- point

The direction of truncation when an integral number is converted to a floating-point number that cannot exactly represent the original value. (6.2.1.3)

22 The direction of truncation or rounding when a floating-point number is converted to a narrow-er floating-point number. (6.2.1.4)

23 size_t The type of integer required to hold the maximum size of an array: that is, the sizeof operator, size_t. (6.3.3.4, 7.1.1).

P1.1.2 Using size_t. □ unsigned int□ int□ Other (     )

24 Type conver-sion (Pointer and integer)

The result of casing a pointer to an integer, or vice versa. (6.3.4)

R2.7.1 Using casts between a pointer and an integer.

1. Pointer->integer□The bit pattern un-

changed□ Other (     )2.Integer->pointer □The bit pattern un-changed□ Other (     )

25 ptrdiff_t The type of integer required to hold the difference between two pointers to members of the same array, ptrdiff_t. (6.3.6,7.1.1).

P1.1.2 Using ptrdiff_t. □ unsigned int□ int□ Other (     )

26 Register specification

The extent to which objects can actually be placed in registers by use of the register storage-class specifier. (6.5.1).

P1.1.2 Using register speci-fiers.

27 union mem-bers access

A member of an union object is accessed using a member of a different type. (6.3.2.3)

M1.6.2 Generally prohibited.

171Appendix C _Documentation templates for implementation-defined items

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

28 Boundary alignment for structure members

The padding and alignment of members of structures. (6.5.2.1)This is not an issue unless binary data written by a processing system are read by another processing system.

R2.1.3 The binary data may be read by other pro-cessing systems using structures. (Note: As-suming that memory overlay is not used. If overlay is used, its description should be given.)

29 Bit-fields Whether a plain int bit-field is treated as a signed int bit-field or as an unsigned int bit-field .(6.5.2.1)

P1.3.3 Using bit-fields of int type without sign specification.

□ signed int□ unsigned int

30 The order of allocation of bit-fields within an int. (6.5.2.1)

P1.3.3 Using bit-fields in a way that the bit loca-tions in the data have a meaning. (Note: As-suming that memory overlay is not used. If overlay is used, its description should be given. )

□ Most significant to least significant

□ Least significant to most significant

31 Whether a bit-field can straddle a storage-unit boundary. (6.5.2.1)

□Straddle boundaries□Allocate to the next

unit

32 enum type The integer type chosen to rep-resent the values of an enumera-tion type. (6.5.2.2)

P1.3.2 Using enumeration types.

□ int□ Other (     )

33 Access to volatile

What constitutes an access to an object that has volatile-qualified type. (6.5.5.3)

P1.1.2 Using volatile quali-fiers.

34 Maximum number of declarators

The maximum number of declarators that may modify an arithmetic, structure, or union type. (6.5.4)

P1.1.2 In most cases, no de-scriptions are neces-sary. (There are few processing systems that impose a small limit to cause prob-lems.)

172 Appendixes

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

35 Maximum number of cases

The maximum number of case values in a switch statement. (6.6.4.2)

P1.1.2 In most cases, no de-scriptions are neces-sary. (There are few processing systems that impose a small limit to cause prob-lems.)

36 Character constants in conditional inclusions

Whether the value of a single-character constant in a constant expression that controls con-ditional inclusion matches the value of the same character con-stant in the execution character set. Whether such a character constant may have a negative value. (6.8.1)

P1.1.2 Using a single-charac-ter constant in con-stant expressions of conditional inclusions.

37 Source file inclusion (#include)

The method for locating includ-able source files.(6.8.2)Note) This item is supposed to be for files enclosed by <>.

P1.4.2 Required. (Rarely unused.)

How to search an include file enclosed by <>.Example:Search in the follow-ing order. 1.Directories specified

by the option.2.Standard directories

in the system

38 The method for locating includ-able source files with names enclosed by “”. (6.8.2)

P1.4.2 Required. (Rarely unused.)

Example:Search in the follow-ing order.1.Directory with

source file.2.The same way with

<>.

173Appendix C _Documentation templates for implementation-defined items

Implementation-defined item in C language standard

Related rules

Use Specification of the target processing system(if the use column has ○, the specification should be explicitly stated)

No. Category

Contents(Cited from C90.Clause numbers of C90 are in ())

Meaning of use Enter ○ if used

39 Source file inclusion (#include)

The mapping of source file char-acter sequences. (6.8.2)

P1.4.2 Example:Interpreted as written literally.

40 #pragma The behavior on each recog-nized #pragma directive (6.8.6)

P1.1.2 Using #pragma Described later (3).

41 __DATE____TIME__

The definitions for __DATE__ and __TIME__ when, respec-tively, the date and time of trans-lation are not available. (6.8.8)

P1.1.2 This functionality is considered to be rarely used. Describe if used.

(1)Basic types, pointers《Refer to the rule P2.1.3. Define cases (including whether there are such cases or not)

where the basic types are not used in the project and give a brief explanation. Delete the lead-ing type name column, if the project does not define another type name for a type defined by the language.》

Project defined type name

Type in C language

Number of bits

Minimum value

Maximum value

Boundary alignment

char

signed char

unsigned char

short

unsigned short

int

unsigned int

long

unsigned long

pointer

174 Appendixes

(2)Behavior of bitwise operators for signed dataBitwise operator Behavior

~

<<

>>

&

^

|

(3)List of #pragmaPragmas that can be used in the project are listed.

Pragma name Function overview

175

Citat ions and References

[1] ISO/IEC 9126:2001, Software engineering – Product quality – Part 1 : Quality model

[2] ISO/IEC 9899:1990, Programming languages – C, ISO/IEC 9899:1990/Cor 1:1994, ISO/IEC 9899:1990/Cor 2:1996,

  ISO/IEC 9899:1990/Amd 1:1995, C Integrity

[3] ISO/IEC 9899:1999, Programming languages – C, ISO/IEC 9899/Cor1:2001

[4] ISO/IEC 14882:2003, Programming languages – C++

[5] “MISRA Guidelines for the Use of the C Language in Vehicle Based Software”, The Motor Industry Software Reliability Association, ISBN 0-9524156-9-0, Apr. 1998, www.misra-c.com

[6] “MISRA-C:2004 Guidelines for the Use of the C Language in Critical Systems”, The Motor Industry Software Reliability Association, ISBN 0-9524156-2-3, Oct. 2004, www.misra-c.com

[7] “Indian Hill Style and Coding Standards”, ftp://ftp.cs.utoronto.ca/doc/programming/ihstyle.ps

[8] “comp.lang.c Frequently Asked Questions”, http://www.eskimo.com/~scs/C-faq/top.html

[9] “GNU coding standards”, Free Software Foundation, http://www.gnu.org/prep/standards/

[10] “The C Programming Language, Second Edition”, Brian W. Kernighan and Dennis M. Ritchie, ISBN 0-13-110362-8, Prentice Hall PTR, Mar. 1988

[11] “Writing Solid Code: Microsoft's Techniques for Developing Bug-Free C Programs”, Steve Maguire, ISBN 1-55615-551-4, Microsoft Press, May 1993

[12] “The Practice of Programming”, Brian W. Kernighan and Rob Pike, ISBN 0-201-61586-X, Addison Wesley Professional, Feb 1999.

[13] “Linux kernel coding style”, http://www.kernel.org/doc/Documentation/CodingStyle

[14] “C Style: Standards and Guidelines: Defining Programming Standards for Professional C Programmers”, David Straker, ISBN 0-1311-6898-3, Prentice Hall, Jan. 1992

[15] “C Programming FAQs: Frequently Asked Questions”, ISBN0-2018-4519-9, Steve Summit

[16] “C STYLE GUIDE (SOFTWARE ENGINEERING LABORATORY SERIES SEL-94-003)”, NASA, Aug. 1994, http://sel.gsfc. nasa.gov/website/documents/online-doc/94-003.pdf

References

176

Authors and editorsAOKI NaoENDO ArisaENDOU Ryuji FURUYAMA Hisaki FUTAGAMI Takao HACHIYA Shouichi HAYASHIDA Seiji HIRAYAMA MasayukiMITSUHASHI Fusako MURO ShujiNAMIKI Rieko OHNO KatsumiOHSHIMA KenjiSHISHIDO FumioUEDA NaokoUNO Musubi

IPA/SECIPA/SECMitsubishi Space Software Co., Ltd.Matsushita Electric Industrial Co., Ltd.TOYO CorporationGAIA System Solutions Inc.TOSHIBA CORPORATIONIPA/SECNEC CorporationIPA/SECOGIS-RI Co., Ltd.IPA/SECRicoh Company, Ltd.eSOL Co., Ltd.FUJITSU LIMITEDMatsushita Electric Industrial Co., Ltd. (Affiliations are as of the publication of Japanese edition)

IPA/SECIPA/SECIPA/SEC

Contributors to English translation versionTOYAMA Keisuke TSUCHIDA Katsumi TSUNODA Sayuri

177References

178

ESCREmbedded System development Coding Reference guide [C language edition]

Ver.1.1

March 31, 2012Written and edited by Software Engineering Center,Technology Headquarters,Information-technology Promotion Agency, Japan

http://www.ipa.go.jp/english/sec/

Copyright © 2012, IPA/SEC