Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
C Coding Guidelines
Overview
C Coding Guidelines
C Code
Assembler
Executable
QA-C
C is a „Dangerous” Language:
capability of constructs which are difficult to understand (“obfuscated C”)
it is easy to write non-portable code
Ease of Maintenance: Today 30-75% of its coding time the average developer
does not implement new code but adapts, corrects or integrates existing code
We base our rules on the “Guidelines For The Use Of The C Language In
Vehicle Based Software” from MISRA
C Programming Guidelines:
“C Coding Guidelines”
platform specific additional guidelines
project/component specific additional guidelines
Design Guidelines:
a few rules in the “C Coding Guidelines”
but: still mostly missing!!
2. “Comments Are For Cowards Only”: of course you know exactly what you are
doing… now; but what will be in 2 years when you (or your colleagues) have to
use (and change!) your code again?
3. “I always used 9 spaces for tabs and ‘1TBS’; that’s simply the best!”:
indenting and brace style indeed are questions of philosophy; for above reasons,
however, the company will decide them, not you
http://c-inside.conti.de/generator/c-
inside/Surf_Regions/en_US/Divisions/automotive/
02_interior/17_business_units/15_infotainment_co
nnectivity/25_departments/r_n_d/engineering_sup
port/070_products_solutions/73_code_check_and
_test_tools/code_check_and_test_tools_en.html
https://workspace1.conti.de/content/00003654/ES
KnowledgeBase/Static%20Code%20Check%20(Q
A-C).aspx
You should understand the rules but you do not need to know them all by
heart because there is help available!
1. ISQP Static Code Checking toolset: using QA-C violations are identified
2. Design Guidelines (when available): following these you will avoid producing
design constructs (e.g. in UML), which will generate rule violations (e.g. in
generated code)
Environment Identifiers
Rule 1 – 4
Rule 11, 12
Comments Constants
Rule 9, 10 Rule 18, 19
Initialisation Expressions
Rule 30 – 32 Rule 46 – 51
Rule 87 - 100
Use
Useofofany
anyother
othercharacters
charactersthan
thanthose
thosedefined
definedininthe
theISO
ISOstandard
standardmay
maybebesupported
supported
by the implementation but will not necessarily be portable to other environments.
by the implementation but will not necessarily be portable to other environments.
Letters:
Letters:
AABBCCDDEEFFGGHHI IJJKKLLMMNNOOPPQQRRSSTTUUVVW WXXYYZZ
aabbccddeef fgghhi ij jkkl lmmnnooppqqr rsst tuuvvwwxxyyzz
Decimal
Decimaldigits:
digits: 00112233445566778899
Graphic
Graphiccharacters:
characters: ! !""##%
%&&' '( () )**++, ,- -. ./ /: :; ;<<==>>??[ [\ \] ]^^__{ {| |} }~~
ISO-C
ISO-CEscape
Escapesequences:
sequences: PC
PCesa
esa=='\a';
'\a'; PC
PCesr
esr=='\r';
'\r';
PC esb = '\b';
PC esb = '\b'; PC est = '\t';
PC est = '\t';
PC
PCesf
esf=='\f';
'\f'; PC
PCesn
esn=='\n';
'\n';
PC esv = '\v';
PC esv = '\v';
These
Thesecharacters
charactersare
arenon-conforming:
non-conforming:$,$,@
@
M7
M7
Trigraphs
Trigraphsshall
shallnot
notbe
beused.
used.
Example
Example(from
(fromANSI
ANSIstandard):
standard): Error:
Error:
The
The following
following source
source line
line (Enter
(Enter date
date in
in format
format ??-??-
??-??-
??);
??);
printf("Eh???/n");
printf("Eh???/n");
is
is being
being interpreted
interpreted by
by the
the
becomes
becomes (after
(after replacement
replacement compiler
compiler asas
of
of the
the trigraph
trigraph sequence
sequence
??/)
??/) (Enter
(Enter date
date in
in format
format ~~];
~~];
printf("Eh?\n");
printf("Eh?\n");
M9
M9
Comments
Commentsshall
shallnot
notbe
benested
nested
The
The character sequence /*shall
character sequence /* shallnot
notbe
beused
usedwithin
withinaacomment
comment
Error:
Error:
/*****
/***** no
no longer
longer used
used
printf("hello
printf("hello ");
"); C does not support the nesting
if of comments. After a /* begins a
if (world)
(world) comment, the comment continues
printf("world!");
printf("world!"); until the first */ is encountered, with
else no regard for any nesting that has
else /*
/* special
special greetings
greetings */
*/ been attempted
printf("guys!");
printf("guys!");
***
*** end
end of
of no
no longer
longer used
used */
*/
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
#include
#include <basetypes>
<basetypes>
unsigned
unsigned char
char velocity;
velocity; UI_8
UI_8 velocity;
velocity;
short
short i;
i; SI_16
SI_16 i;
i;
...
... ...
...
M14
M14
The
Thetype
typechar
charshall
shallalways
alwaysbe
bedeclared
declaredas
asunsigned
unsignedchar
charor
or
signed char
signed char
The
Theplain
plainchar
chartype
typeshall
shallbe
beused
usedonly
onlyfor
forstorage
storageand
anduse
useof
ofcharacter
charactervalues.
values.
signed
signed and unsigned char type shall be used only for the storage and useofof
and unsigned char type shall be used only for the storage and use
numeric
numericvalues.
values.
There are three distinct char types: (plain) char, signed char and unsigned char.
This rule is effectively requiring that type char should not be used.
Rather than making any assumptions about the compiler, it is preferable to
always specify whether the required use of char is signed or unsigned.
If Rule 13 is being followed then this rule should only be relevant in setting up
the initial typedefs.
The exact storage layout used for floating point numbers may vary from one compiler
to another and, therefore, no floating point manipulations should be made which rely
directly on the way the numbers are stored.
The underlying bit representation of floating point members can be accessed by
using unions with members of floating type. Rule 110 prohibits the use of unions.
M17
M17
Typedef
Typedefnames
namesshall
shallnot
notbe
bereused.
reused.
AAtypedef
typedefname
nameshall
shallbe
beaaunique
uniqueidentifier.
identifier.
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
const
const char
char zero
zero == 000;
000; const
const char
char zero
zero == 0;
0;
const
const char
char one
one == 001;
001; const
const char
char one
one == 1;
1;
...
... ...
...
const
const char
char seven
seven == 007;
007; const
const char
char seven
seven == 7;
7;
const
const char
char ten
ten == 010;
010; const
const char
char ten
ten == 8;
8;
...
... ...
...
const
const char
char hundred
hundred == 100;
100; const
const char
char hundred
hundred == 64;
64;
M21
M21
Identifiers
Identifiersininan
aninner
innerscope
scopeshall
shallnot
notuse
usethe
thesame
samename
nameas
asan
anidentifier
identifierininthe
the
outer scope and therefore hide that identifier.
outer scope and therefore hide that identifier.
SI_16 i;...
{
SI_16 i;//This is a different variable
i = 3;//it can be confusing as to which i this refers to
}
M22
M22
Declaration
Declarationofofobjects
objectsshould
shouldbe
beatatfunction
functionscope
scopeunless
unlessaawider
widerscope
scopeisis
necessary.
necessary.
M25
M25
An
Anidentifier
identifierwith
withexternal
externallinkage
linkageshall
shallhave
haveexactly
exactlyone
oneexternal
externaldefinition.
definition.
Outside
Outside of
of any
any function,
function, the defined external
the defined variables sp
external variables and val
sp and val cause
cause storage
storage to
to
be set aside:
be set aside: int sp;
int sp;
double
double val[MAXVAL];
val[MAXVAL];
On
On the
the other
other hand,
hand, the
the lines
lines below declare for
below declare for the
the rest
rest of
of the
the source
source file
file the
the
integer sp the double array val, but they do not reserve storage
integer sp the double array val, but they do not reserve storage for them: for them:
extern
extern int
int sp;
sp;
extern double val[];
extern double val[];
There
There must
must be
be only
only one definition of
one definition of an
an external
external variable
variable among
among all
all the
the files
files that
that
make
make up the source program; other files may contain extern declarations to access it.
up the source program; other files may contain extern declarations to access it.
file1:
file1: file2:
file2:
extern
extern int
int sp;
sp; int
int sp
sp == 0;
0;
extern
extern double
double val[];
val[]; double
double val[MAXVAL];
val[MAXVAL];
void
void push (double f)
push (double f) {{ ...use
...use of
of sp
sp and
and val...
val... }}
double
double pop
pop (void)
(void) {{ ...
... use
use of
of sp
sp and
and val...
val... }}
M26
M26
IfIfobjects
objectsor
orfunctions
functionsare
aredeclared
declaredmore
morethan
thanonce
oncethey
theyshall
shallhave
havecompatible
compatible
declarations.
declarations.
M27
M27
External
Externalobjects
objectsshould
shouldnot
notbe
bedeclared
declaredininmore
morethan
thanone
onefile.
file.
M29
M29
The
Theuse
useofofaatag
tagshall
shallagree
agreewith
withits
itsdeclaration.
declaration.
Where a tag has been given in the declaration of a structure, union or enumeration
type, all subsequent uses of the tag shall be consistent with the declaration.
Example
Example
Incorrect:
Incorrect: Static variables are automatically
uint8 initialized to zero. Local variables,
uint8 x;
x;
however, may or may not be
uint8
uint8 y;y; automatically initialized and,
yy == x;
x; /*MISRA
/*MISRA Violation*/
Violation*/ therefore, no reliance should be
placed on this mechanism.
...
... /*
/* no
no assignment
assignment to
to xx */
*/
if
if (x>0)
(x>0) /*MISRA
/*MISRA Violation*/
Violation*/
{{ ...
...
M31
M31
Braces
Braces‘{’‘{’‘}’‘}’shall
shallbe
beused
usedto
toindicate
indicateand
andmatch
matchthe
thestructure
structureininthe
thenon-zero
non-zero
initialization of arrays and structures.
initialization of arrays and structures.
Example
Example
Incorrect: ISO C requires initializer lists for arrays,
Incorrect: structures and union types to be
UI_8
UI_8 array[3][2]
array[3][2] == {1,
{1, 2,
2, 3,
3, 4,
4, enclosed in a single pair of braces. The
5, 6}
5, 6} rule requires the use of additional braces
to indicate nested structures.
Correct:
Correct:
UI_8
UI_8 array[3][2]
array[3][2] == {{1,
{{1, 2},
2}, {3,
{3, All the elements of arrays and
4},
4}, {5,
{5, 6}}
6}} structures can be initialized to zero or
NULL by giving an explicit initializer for
the first element only.
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
#define
#define VAL
VAL 4294
4294 enum
enum game
game
enum {{ tennis
tennis == 2,
2, cricket,
cricket, golf,
golf, hurling
hurling
enum color
color }}
{red,
{red, blue
blue == VAL,
VAL, green
green };
};
enum enum
enum town{
town{ London,
London, Paris,
Paris, New_York};
New_York};
enum car
car
{BMW,
{BMW, VW,
VW, Ford
Ford == VAL
VAL };
};
enum
enum country
country
{Germany
{Germany == 1,
1, Italy
Italy == 2,
2, Australia
Australia ==
3};
3};
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
if((x
if((x >> 0)
0) &&
&& foo_SET(x)) if
foo_SET(x)) if ((x
((x >> 0)
0) &&
&& foo_GET(x))
foo_GET(x))
if(foo_SET(x)
if(foo_SET(x) && (x >> 00))
&& (x ))
IfIf(x>0)
(x>0)guards
guardsthe
thecall
callofoffoo_SET:
foo_SET:
This
This needs deviation grant......
needs deviation grant
The conditional evaluation of the right hand operand can easily cause problems if the
programmer relies on a side-effect occurring.
M34
M34
The
Theoperands
operandsofofaalogical
logical&&
&&or
or||||shall
shallbe
beprimary
primaryexpressions.
expressions.
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
if(
if( (x
(x >> 0)
0) &&
&& a=foo(x)
a=foo(x) )) aa == foo(x);
foo(x);
if(a
if(a &&&& (x>0)
(x>0) )) ...
...
if(
if( (x==0)
(x==0) &&
&& ishigh
ishigh )...
)...
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
if(
if( (x
(x == y)!=0
y)!=0 )) xx == y;
y;
{{ if
if (( x!=0
x!=0 ))
foo();
foo(); {{
}} foo();
foo();
Worse:
Worse: }}
if(
if( xx == y)
y) ...
...
M37
M37
Bitwise
Bitwiseoperations
operationsshall
shallnot
notbe
beperformed
performedon
onsigned
signedinteger
integertypes.
types.
Problems can arise if, for example, a right shift moves the sign bit into the number or
a left shift moves a numeric bit into the sign bit.
If the left-hand operand of a left shift or a right shift is a 16 bit integer, then it is
important to ensure that this is shifted only by a number between 0 and 15. The
simplest thing that can be done is for the right-hand operand to be a constant (value
can be statically checked).
M39
M39
The
Theunary
unaryminus
minusoperator
operatorshall
shallnot
notbe
beapplied
appliedto
toan
anunsigned
unsignedexpression.
expression.
U32 r;
S32 s;
U16 X;
U16 u = 1;
x = sizeof ( S16 );
x = x + sizeof ( u );
x = x + sizeof ( u++ ); /*MISRA Violation*/
x = x + sizeof ( function() ); /*MISRA Violation*/
M43
M43
Implicit
Implicitconversions
conversionswhich
whichmay
mayresult
resultininaaloss
lossofofinformation
informationshall
shallnot
notbe
beused.
used.
Example
Example Implicit conversions (can results in loss of information)
Incorrect:
Incorrect: shall not be used, but explicit casts should be used
instead.
int8
int8 x; x; Avoid mixing arithmetic of different precisions in the
uint16
uint16 y;y; same expressions and avoid mixing signed and unsigned
uint8
uint8 z; z; integers in the same expression.
...
... Explicit type casting should not be used unnecessarily as
xx == y;
y; this may prevent SCC tools from detecting errors. Explicit
yy == x;
x; casts should only be used in the case where a
zz == x;
x; conversion which could result in a loss of information is
xx == z;
z; specifically required by the programmer.
Error:
Error:
static This can lead to undefined or
static U32
U32 addr
addr == 0x1234UL;
0x1234UL;
implementation-defined behavior.
static
static const
const S16
S16 ci
ci == 0x3333;
0x3333;
static A fundamental danger with pointer
static F64
F64 db;
db;
casts is attempting to cast a
const
const S8
S8 *pcc;
*pcc; pointer to a type with a stricter
const
const S16
S16 *pci
*pci == &ci;
&ci; alignment.
This might occur when casting a
addr
addr == (U32)
(U32) pci;
pci; /*MISRA Violation*/
/*MISRA Violation*/ char* to an int*; if the char* may
db
db == (F64)
(F64) pci;
pci; /*MISRA
/*MISRA Violation*/
Violation*/ reside on any byte boundary, an
pcc int* is constrained to alignment on
pcc == (const
(const S8*)
S8*) pci;
pci; /*MISRA
/*MISRA Violation*/
Violation*/
a 4 byte boundary.
pci
pci == (const
(const S16*)
S16*) pcc;
pcc; /*MISRA
/*MISRA Violation*/
Violation*/
M46
M46
The
Thevalue
valueofofan
anexpression
expressionshall
shallbe
bethe
thesame
sameunder
underany
anyorder
orderofofevaluation
evaluationthe
the
standard permits
standard permits..
Example
Example Example
Example
Incorrect:evaluation Correct:
Correct:
Incorrect:evaluation order?
order?
xx == b[i] xx == b[i]
b[i] ++ i;
b[i] ++ i++;
i++; i;
i++;
i++;
xx == f(a) xx == f(a);
g(a);//modifying global
f(a) ++ g(a);//modifying global data
data f(a);
x+
x+ == g(a);
g(a);
xx == func(y
func(y == z/3);//nested
z/3);//nested assignment
assignment
xx == (x xx == ((x+1)>MAX)?(x+1):0;
(x >> MAX)
MAX) ?? (++x)
(++x) :: 0;
0; ((x+1)>MAX)?(x+1):0;
M48
M48
Mixed
Mixedprecision
precisionarithmetic
arithmeticshould
shoulduse
useexplicit
explicitcasting
castingto
togenerate
generatethe
thedesired
desired
result.
result.
Example
Example Example
Example
Incorrect:
Incorrect: Correct:
Correct:
UI_16
UI_16 ii == 1u;
1u; UI_16
UI_16 ii == 1u;
1u;
UI_16 j = 3u;
UI_16 j = 3u; UI_16 j = 3u;
UI_16 j = 3u;
F_64 F_64
F_64 d2
d2 == (F_64)
(F_64) ii // j;//0.333
F_64 d0
d0 == ii // j;//0.0
j;//0.0 j;//0.333
F_64 F_64
F_64 d3 = (F_64) i / (F_64)j;//0.333
d3 = (F_64) i /
F_64 d1
d1 == (F_64)(i
(F_64)(i // j);//0.0
j);//0.0 (F_64)j;//0.333
UI_16 UI_16
UI_16 ii == 65535u;
UI_16 ii == 65535u;
65535u; 65535u;
UI_16 j = 10u; UI_16 j = 10u;
UI_16 j = 10u;
UI_16 j = 10u;
UI_32 UI_32
UI_32 e2
e2 == (UI_32)
(UI_32) ii ++ j;//65545
j;//65545
UI_32 e0
e0 == ii ++ j;//9
j;//9 UI_32
UI_32 UI_32 e3 = (UI_32) i + (UI_32) j;//65545
e3 = (UI_32) i + (UI_32) j;//65545
UI_32 e1
e1 == (UI_32)
(UI_32) (i(i ++ j);//9
j);//9
Comparisons of equality will often not evaluate to true even when they are expected
to (implementation dependent).
Error:
Error: Example:
Example:
float
float one_third
one_third == const
const float
float EPSILON
EPSILON == 0.001f;
0.001f;
1.0/3.0;
1.0/3.0; float
float one_third
one_third == 1.0F/3.0F;
1.0F/3.0F;
for
for (float
(float xx == 1.0;
1.0; //FLOAT_ABS
//FLOAT_ABS is
is ABS
ABS returning
returning aa float
float
xx !=
!= for
for (i = 1.0f; FLOAT_ABS(i - one_third) >>
(i = 1.0f; FLOAT_ABS(i - one_third)
one_third;
one_third; EPSILON;
EPSILON; i-=i-= one_third)
one_third)
xx -=
-=
one_third)
one_third) {{ ...
...
{{ ...
...
M52
M52
There
Thereshall
shallbe
beno
nounreachable
unreachablecode.
code.
Example: Example:
S32 i = 1; switch ( x )
if ( i > 0 ) { ... } {
S16 y = 1;
else { ... }
/*unreachable*/ case 0: ...
M56
M56
The
Thegoto
gotostatement
statementshall
shallnot
notbe
beused.
used.
Examples:
Examples:
sint32_t Even a single statement is to be enclosed
sint32_t ii == 5;
5; within braces to avoid the danger of adding
if(i<10){ code which is intended to be part of the
if(i<10){ }}
// conditional block but is actually not.
// instead
instead of
of if(i<10);
if(i<10);
Sometimes, everything that is to be done in
if(i){
if(i){ }} a loop may be easily written on one line in
else{
else{ }} the loop statement itself. It may then be
tempting to conclude the statement with a
while(1){}
while(1){}
//instead semicolon at the end of the line. This may
//instead of
of while(1);
while(1); lead to misunderstanding since it is easy to
for(i=0; miss such a semicolon.
for(i=0; i<1;
i<1; i++){}
i++){}
//instead
//instead of
of for(i=0;
for(i=0; i<1;
i<1; i++);
i++);
M61
M61
Every
Everynon-empty
non-emptyclause
clauseininaaswitch-statement
switch-statementshall
shallbe
beterminated
terminatedwith
withaa
break-statement.
break-statement.
M62
M62
All
Allswitch
switchstatements
statementsshould
shouldcontain
containaafinal
finaldefault
defaultclause.
clause.
‘final’
‘final’ means that the Default case shall be at the endofofthe
means that the Default case shall be at the end theswitch.
switch.
M64
M64
Every
Everyswitch
switchstatement
statementshall
shallhave
haveatatleast
leastone
onecase.
case.
Example
Example Rounding and truncation errors can
Incorrect: be propagated through the iterations of
Incorrect: the loop, causing significant
S16
S16 test_065(
test_065( F32
F32 ff ))
{{ inaccuracies in the loop variable. For
F32 example, the number of times a loop is
F32 n;
n;
for
for (n == 0.0F;
(n 0.0F; nn << f;
f; n++)
n++)
performed may vary from one
{{ ... }
... } implementation to another and may be
}} unpredictable.
M68
M68
Functions
Functionsshall
shallalways
alwaysbe
bedeclared
declaredon
onfile
filescope.
scope.
Error:
Error: Example:
Example:
int
int sum(...);
sum(...); int
int sum(int
sum(int x1,
x1, int
int x2);
x2);
int
int sum(int x1, int x2, int
sum(int x1, int x2, int x3);
x3);
This precludes the use of stdarg.h, va_arg, va_start and va_end, and the ellipsis
notation in function prototypes.
M70
M70
Functions
Functionsshall
shallnot
notcall
callthemselves,
themselves,either
eitherdirectly
directlyor
orindirectly.
indirectly.
Recursive function calls cannot be used in safety related systems. Recursion carries
with it the danger of exceeding available stack space, which can be a serious error.
M71
M71
Functions
Functionsshall
shallalways
alwayshave
haveprototype
prototypedeclarations
declarationsand
andthe
theprototype
prototypeshall
shallbe
be
visible at both the function definition and call.
visible at both the function definition and call.
M75
M75
Every
Everyfunction
functionshall
shallhave
havean
anexplicit
explicitreturn
returntype.
type.
Approx. 26% of all statically detectable faults in C code can be prevented by proper use of
the function prototype mechanism. The use of prototypes enables the compiler to check
the integrity of function definition and calls.
Functions shall always be declared with a return type, that type being void if the function
does not return any data. Similarly, if the function has no parameters, the parameter list
should be declared as void.
M78
M78
The
Thenumber
numberofofparameters
parameterspassed
passedto
toaafunction
functionshall
shallmatch
matchthe
thefunction
function
prototype
prototype
This rule helps to prevent the modification of a function parameter which is intended
as input only.
Example
Example(Correct):
(Correct):
//the
//the const
const qualification
qualification should
should be
be applied
applied to
to the
the object
object pointed
pointed
//to and not to the pointer, since the object itself is
//to and not to the pointer, since the object itself is being being
//protected
//protected
void
void func(const
func(const SI_16
SI_16 *myparam)
*myparam)
{{ *myparam
*myparam == 2;//Attempt
2;//Attempt to
to modify
modify value
value pointed
pointed to
to by
by myparam
myparam
}} //
// const
const prevents
prevents this
this
M83
M83
For
Forfunctions
functionswith
withnon-void
non-voidtype
type: :
--there
thereshall
shallbe
beone
onereturn
returnstatement
statementfor
forevery
everyexit
exitbranch
branch
(including the end of the program),
(including the end of the program),
--each
eachreturn
returnshall
shallhave
haveananexpression,
expression,
--the
thereturn
returnexpression
expressionshall
shallmatch
matchthe
thedeclared
declaredreturn
returntype.
type.
(Example
(Examplefollows
followson
onnext
nextslide)
slide)
S16 test_2(S16 j)
{ S16 r;
r = j + 2;
return; } /*No expression in return statement*/
S16 test_3(void)
{ F32 f = 1.0F;
return (f); } /*Return expression has wrong type*/
enum Colors {Red, Blue, Green}; enum Fruit {Lemon, Orange, Apple};
M85
M85
Functions
Functionscalled
calledwith
withno
noparameters
parametersshould
shouldhave
haveempty
emptyparenthesis.
parenthesis.
It is important to prevent the situation where executable code comes before the
#include directive, because there is the danger that the code tries to use items
defined in the header.
M88
M88
Non-standard
Non-standardcharacters
charactersshall
shallnot
notoccur
occurininheader
headerfile
filenames
namesinin#include-
#include-
directives.
directives.
If the ', \, " or /* characters are used between the <> delimiters or the ', \ or /*
characters are used between the " " delimiters in a header name, then the behavior
is undefined.
#include <path-spec> – instructs the preprocessor to search for include files first
along the path specified by the /I compiler option, then, along the path specified by
the INCLUDE environment variable.
While it is legal C to place #define and #undef directives anywhere in a file, placing
them inside blocks is misleading, as it implies a scope restricted to that block.
Normally, #define directives will be placed near the start of a file, before the first
function definition.
M94
M94
AAfunction-like
function-likemacro
macroshall
shallnot
notbe
be"called"
"called"without
withoutall
allofofits
itsarguments.
arguments.
If any of the arguments to a function like macro look like pre-processor directives, the
behavior when the macro substitution is made can be unpredictable.
#define SUM(A,B,C) ((A) + (B) + (C))
extern S16 test_095(void) {
#if 0 /* QAC will not parse the following code.
s16a = SUM( 5,
#ifdef SW /* MISRA Violation */
s16b,
#else /* MISRA Violation */
s16c,
#endif /* MISRA Violation */
0 );
#endif
return 1; }
z = abs(a - b);
z = a – b >= 0 ? a – b : -a – b; // - (a – b) was
intended
z = abs(a) + 1;
z = a > 0 ? a : -a + 1; //not intended
M98
M98
There
Thereshall
shallbe
beatatmost
mostoneonedefinition
definitionofofthe
the##and
and##
##preprocessor
preprocessoroperators
operatorsinin
aasingle
singlemacro
macrodefinition.
definition.
There is an issue of unspecified order of evaluation associated with the # and the ##
pre-processor operators. To avoid this, only one occurrence of one operator may be
used in any single macro definition (one # OR one ## OR neither).
M99
M99
All
Alluses
usesofofthe
the#pragma
#pragmadirective
directiveshall
shallbe
bedocumented
documentedand
andexplained.
explained.
The meaning of each #pragma shall be documented and there shall be sufficient
description to demonstrate that the behavior of the #pragma and its implications for
the application have been fully understood.
The
The special operator defined
special operator defined is
is used
used in
in #if
#if and
and #elif
#elif expressions
expressions
to test whether a certain name is defined as a
to test whether a certain name is defined as a macro. macro.
M102
M102
No
Nomore
morethan
than22levels
levelsofofpointer
pointerindirection
indirectionshould
shouldbe
beused.
used.
The use of more than 2 levels of indirection can seriously impair the ability to
understand the behavior of the code and should, therefore, be avoided.
M103
M103
Relational
Relationaloperators
operatorsshall
shallnot
notbe
beapplied
appliedtotopointer
pointertypes
typesexcept
exceptwhere
whereboth
both
operands
operands are of the same type and point to the same array, structure orunion.
are of the same type and point to the same array, structure or union.
Attempting to compare two pointers that do not point to the same object will produce
undefined behavior.
QAC partially enforces this rule. Static analysis can check that pointer types are of
the same type but cannot always detect that they point to the same array, structure
or union.
static S8 tab1[] = "test1";
static S8 tab2[] = "test2";
S8 * ptr1;
S8 * ptr2;
if (ptr1 > ptr2) /*MISRA Violation – not detected*/
{ ... }
if (&tab1[0] > &tab2[0]) /*MISRA Violation – not detected*/
{ ... }
M108
M108
In
Inthe
thespecification
specificationofofaastructure
structureor
orunion-type,
union-type,all
allmembers
membersofofthe
thestructure
structureor
or
union shall be fully specified.
union shall be fully specified.
If this rule is not followed it will lead to an incomplete type, which should be avoided.
M109
M109
Overlapping
Overlappingvariable
variablestorage
storageshall
shallnot
notbe
beused.
used.
This rule refers to the technique of using memory to store some data, then using the
same memory to store some other data during the execution of the program. Clearly
it relies on the two different pieces of data existing at disjoint period of the program's
execution and never being required simultaneously.
This practice is not recommended for safety-related systems as it brings with it a
number of dangers.
Example: a program may try to access data of one type from the location when
actually it is storing a value of the other type (due to an interrupt). The two types
may align differently in the storage and encroach upon other data. Data may not be
correctly initialized every time the usage switches.
M112
M112
Bit
Bitfields
fieldsofoftype
typesigned
signedint
intshall
shallbe
beatatleast
least22bits
bitslong.
long.
struct bitest
{
signed int is_key: 1; /* MISRA Violation */
signed int is_ctr: 3;
} obj;
It is generally bad practice to #undef or #define names which are C reserved words
or which are function names in any of the standard libraries. In addition there are
some specific reserved words and function names which are known to lead to
undefined behavior if they are redefined or undefined, including defined, __LINE__,
__FILE__, __DATE__, __TIME__, __STDC__, errno and assert.
#define defined !defined /* MISRA Violation */
#undef __LINE__ /* MISRA Violation */
#undef __FILE__ /* MISRA Violation */
#define __LINE__ 1 /* MISRA Violation */
#define __FILE__ "default" /* MISRA Violation */
#define __DATE__ "01-01-2000" /* MISRA Violation */
#define errno 1 /* MISRA Violation */
#define int long /* MISRA Violation */
Where new versions of standard functions are produced by the programmer, the
modified function shall have a new name. This is to avoid any confusion as to
whether a standard function is being used or a modified one.
Identifiers with '_' are reserved for library use.
M118
M118
Dynamic
Dynamicheap
heapmemory
memoryallocation
allocationshall
shallnot
notbe
beused.
used.
This precludes the use of the functions calloc, malloc, realloc and free.
Note that some implementations may use dynamic heap memory allocation to implement
other functions (for example functions in string.h). If this is the case then these functions
shall also be avoided.
M119
M119
The
Theerror
errorindicator
indicatorerrno
errnoshall
shallnot
notbe
beused.
used.
Use of this macro can lead to undefined behavior when the types of the operands
are incompatible or when bit fields are used.
struct stag
{
S32 a;
F64 b;
}s;
size_t p;
s.a = 1;
s.b = 0.0;
Example:
Example:
jmp_buf
jmp_buf env;
env; //Type
//Type to
to hold
hold information
information to
to restore
restore the
the environment
environment at
at the
the setjmp's
setjmp's calling
calling
point.
point.
int SomeFunction(int a, int b)
int SomeFunction(int a, int b)
{{
if
if (b
(b ==
== 0)
0) {{ longjmp(env,
longjmp(env, -3);
-3); }} /*MISRA
/*MISRA Violation*/
Violation*/
return a / b;
return a / b;
}}
void
void main()
main()
{{ //setjmp
//setjmp -- saves
saves calling
calling environment
environment for
for longjump
longjump
int val = setjmp(env); /*MISRA Violation*/
int val = setjmp(env); /*MISRA Violation*/
if (val == 0)
if (val == 0)
{
{
int
int Result
Result == SomeFunction(7,
SomeFunction(7, 0);
0);
... // continue working with Result
... // continue working with Result
}
}
else
else
{{ printf("an
printf("an error
error occured\n");
occured\n"); }} }}
M123
M123
The
Thesignal
signalhandling
handlingfacilities
facilitiesof
of<signal.h>
<signal.h>shall
shallnot
notbe
beused.
used.
This includes file and I/O functions fgetpos, fopen, ftell, gets, perror, remove,
rename and ungetc.
Streams and file I/O have a large number of unspecified, undefined and
implementation-defined behaviors associated with them. It is assumed that they will
not normally be needed in production code in embedded systems.
M125
M125
The
Thelibrary
libraryfunction
functionatof,
atof,atoi
atoiand
andatol
atolfrom
fromlibrary
library<stdlib.h>
<stdlib.h>shall
shallnot
notbe
beused.
used.
These functions have undefined behavior when the string cannot be converted.
M126
M126
The
Thelibrary
libraryfunction
functionabort,
abort,exit,
exit,getenv
getenvand
andsystem
systemfrom
fromlibrary
library<stdlib.h>
<stdlib.h>shall
shall
not be used.
not be used.
These functions will not normally be required in embedded systems which do not
normally need to communicate with an environment.
M127
M127
The
Thetime
timehandling
handlingfunctions
functionsfrom
fromlibrary
library<time.h>
<time.h>shall
shallnot
notbe
beused.
used.
Includes time, strftime. This library is associated with clock times. Various aspects
are implementation dependent or unspecified, such as formats of times.
00 Information
Information
22 Minor
Minor
33 Major
Major Logical
LogicalErrors
Errors
66 Portability
Portability Dangerous
DangerousCC
constructs
constructs
77 Undef.
Undef. behavior
behavior
Cover
Cover MISRA
MISRARules
Rules
88 Lang.
Lang.constraints
constraints
99 Errors
Errors CCSyntax
SyntaxErrors
Errors
Smaranda RADAUCEANU| ES IAS
IfIf you
you do
do not
not understand
understand aa message
message there
there isis help
help inin the
the QA-C
QA-C installation
installation
explaining the QA-C messages:
explaining the QA-C messages:
\\iasp351x\didl9505\SCC\QA_C\v7.1\help\messages\<message#>
\\iasp351x\didl9505\SCC\QA_C\v7.1\help\messages\<message#>
When
Whenyouyouthink
thinkyou
youare
arefinished,
finished,do
doaafinal
finalcheck
checkover
overthe
thefull
fullproject,
project,as
as
QA-C finds more problems when analyzing the complete project (non-local
QA-C finds more problems when analyzing the complete project (non-local
problems)
problems)
Check
Checkearly,
early,whenever
wheneveryou
youfinish
finishaaCCmodule
module
You
Youcan
canavoid
avoidmost
mostmessages
messagesififyou:
you:
follow
followour
ourCCCoding
CodingGuidelines
Guidelines
flag
flagyour
yourconstants
constantsunsigned
unsignedor
orcast
castto
tothe
theright
righttype:
type:
#define
#defineCONSTANT
CONSTANT0xFFC0U
0xFFC0U
#define
#defineTNATSNOC
TNATSNOC((T_UBYTE)
((T_UBYTE)0xC0)
0xC0)
qualify
qualifypointers
pointersin
inaaparameter
parameterlist
listof
ofaafunction
functiondefinition
definitionas
as‘const’:
‘const’:
void
void my_function(
my_function( T_UBYTE
T_UBYTE value,
value, const
const T_UWORD
T_UWORD
*ruwp_read_only_ptr);
*ruwp_read_only_ptr);
check
checkyour
yourcode
codeearly
earlyand
andoften!
often!