this is a translation of escr (embedded system ... preface in recent years, the scale of embedded...
TRANSCRIPT
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