You are on page 1of 67

MISRA-C Standard contains following rule groups :

Environment -- rule1 , rule3


Character Sets -- rule5, rule7 , rule8
Comments -- rule9, rule10
Identifiers -- rule11, rule12
Types -- rule13, rule14, rule16, rule17
Constants -- rule18, rule19
Declarations and Definitions -- rule20 to rule29
Initialisation -- rule30, rule31, rule32
Operators -- rule33 to rule40, rule42
Conversions -- rule43, rule44, rule45
Expressions -- rule46 to rule51
Control Flow -- rule52 to rule67
Functions -- rule68 to rule86
Pre-Processing Directives -- rule87 to rule100
Pointer and Arrays -- rule101 to rule107
Structures and Unions rule108 to rule113
Standard Libraries -- rule114,rule115, rule118 to rule127

Rule Descriptions:-
Name rule1
Text All code shall conform to ISO 9899 standard C, with no extensions permitted
Severity Required
Description
It is recognised that it may be necessary to raise deviations to
permit certain language extensions, for example to support hardware
specific features.

Name rule3
Text Assembly language code shall not be embedded within normal C code
Severity Advisory
Description
Assembly language code should not be embedded within normal C-code.
However, where assembly language instructions are required it is
recommended that they be encapsulated in a C function which is
written solely for this purpose. Implementing such a function then
makes use of built-in parameter passing mechanisms of C-language.

Name rule5
Text Only those characters and escape sequences which are defined in the ISO-C standard
shall be used
Severity Required
Description
These are the minimum source character set for all compilers. These
are the only characters that should be used, even if the compiler
supports a larger character set, or supports alternative character
sets.
Name rule7
Text Trigraphs shall not be used
Severity Required
Description
Trigraphs are denoted by a sequence of two question marks followed
by a specified third character(e.g. ??- represents a '~'(tiled)
character and ??) represents a ']' ). They can cause accidental
confusion with other uses of two question marks.

Example :

'(Date should be in the form ??-??-??)'

will not behave as expected, because it is interpreted by the


compiler as

'(Date should be in the form ~~]'

Therefore trigraphs should be avoided.

Name rule8
Text Multibyte characters and wide string literals shall not be used
Severity Required
Description
Multibyte characters provide a way to extend the source character
set. There are various undefined and implementation-defined behaviors
that are associated with them. They should not be used.

Example:

/* Non-Conforming because - Wide string literals used here */


wchar_t cstr ;
cstr = L'12' ;

Name rule9
Text Comments shall not be nested
Severity Required
Description
C does not support the nesting of comments. A comment begins after a
'/*' and continues until the first '*/' is encountered. If any nesting
is attempted, it will be disregarded.

Name rule10
Text Sections of code should not be commented out
Severity Advisory
Description
If a section of code does not need be compiled then conditional
compilation (e.g. #if or #ifdef constructs) can be used.
Using start and end of comment markers for this purpose is dangerous
because C-language does not support nested comments. Any comments that
already exist in the section of code would change the effect.

Following should be avoided:


for ( counter = 0 ; counter < 10 ; counter++)
{
/* if ( hike[counter] < 20000)
hike[counter] = 20000 + 0.01 *
salary[counter];
else */ /* This type of commenting should be avoided
*/
{
hike[counter] = 20000 + 0.05 * hike[counter];
}
}

Note: As comments may contain arbitrary text, it is extremely difficult


to parse the comment to determine if it contains any source
code-fragments.
Therefore, determining that a comment does not contain source code is
necessarily done through some heuristics. Any line that ends in a ';'
or any set of lines that begins with a '{' and end with a '}' is assumed
to be source code.

This approximation enables Assent to catch many real violations of the


rule without reporting too many spurious violations.

Name rule11
Text Identifiers shall not rely on significance of more than 31 characters
Severity Required
Description
Rule is to ensure that code can be ported between the majority of
compilers / linkers without requiring modification ( shortening ) of
parameter-names.

Problem is related with usage of identifier-names that differ by only


one or few characters, especially if the identifier-names are long and
if the differences are in mis-leading characters like 1 (one) and l
(lower case L), 0 and O,5 and S etc. It is recommended to ensure that
identifier-names are always easy to distinguish,visually.

For Example :-

Following two identifiers may not differ for some compilers.

varToCheckForTopDisplayButtonToBeExit
varToCheckForTopDisplayButtonToBeShow

Name rule12
Text No identifier in one name space shall have the same spelling as an identifier in another
name space
Severity Advisory
Description
It is technically possible to use the same name space separately to
reprsent completely different items.However this practice is deprecated
because of the confusion it can cause. Hence names should not be reused,
even in separate name spaces.
An exception to this rule is the naming of members of structures, where
member names may be reused within separate structures.

For Example :-

enum chk {lbl,lbl2,lbl3}; /* for lbl2*/


if (i == 2)
goto lbl2;
x = 5;
lbl2 : x = 10; /* label lbl2 conflicts with enumeration
literal lbl2 */

Name rule13
Text The basic types of char, int, short, long, float and double should not be used, but
specific-length equivalents should be typedef'ed for the specific compiler, and these type
names used in the code
Severity Advisory
Description
The storage length of types can vary from compiler to compiler. It is
safer if programmers work with types which they know to be given length.

For Example:

On a platform where integers are 32 bit and short integers


are 16 bit, the header file would contain the typedef :
typedef unsigned int UI_32;
typedef signed short SI_16;

/* Non-Conforming because - Identifier is of a non-typedef'ed basic


type.*/
int ival;
short sval;

Note: Assent checks that basic types such as char, int and short are
not used as is in the source code but are typedef'ed and used. However,
it cannot check that the typedef names are either meaningful or contain
the correct size equivalents for the specific compiler to be used in
development.

Name rule14
Text The type char should be declared as signed char or unsigned char
Severity Required
Description
The type char may be implemented as a signed char or unsigned char
type depending on compiler.It is preferable (and more portable) to
always specify whether the required use of char is signed or unsigned.

Example:

typedef char CHAR;


/* Non-Conforming because - cval is not declared as signed or
unsigned */
CHAR cval;

typedef unsigned char UCHAR;

/* Conforming because - ucval is declared as unsigned */


UCHAR ucval;

Name rule16
Text The underlying bit representations of floating point numbers shall not be used in any way
by the programmer
Severity Required
Description
The exact storage layout used for floating point numbers may vary
from one compiler to another. Therefore no floating point manipulations
should be made which rely directly on the way numbers are stored. The
in-built operators and functions, which hide the storage details from
the programmer, should be used.

Example:

typedef unsigned int INT32;


typedef float FLOAT;
typedef double DOUBLE;
typedef long double LDOUBLE;

void f1(INT32 i, INT32 j)


{
FLOAT f = 1.0f;
DOUBLE d = 2.0;
LDOUBLE ld = 3.0;

/* Non-Conforming because - Bitwise operation is performed on


floating-point expression that is cast to an integral type.*/
i = (INT32) f << 2;
j = ~(INT32) d;
i &= (INT32)f;
}

Note: This rule states the underlying bit representation of a floating


point number shall not be used in any way. Assent checks for this rule
by ensuring that no bit-wise operation is performed on a floating-point
expression even if the floating-point expression is cast to an integral
type.

Name rule17
Text Typedef names shall not be reused
Severity Required
Description
Once a name has been assigned as a typedef it should not be used for
any other purpose in any of the code files.
Example:

typedef unsigned char UCHAR;


UCHAR mychar;

void myIntclone (void)


{
/* Non-Conforming because - Also used as function name */
typedef unsigned int myIntclone;

/* Non-Conforming because - Also used as other identifier name */


typedef char mychar2;

/* Non-Conforming because - Also used as other typedef name */


typedef short INT;
}

/* Non-Conforming because - Also used as other typedef name */


typedef int INT;

INT main(void)
{
char mychar2;
myIntclone();

return 0 ;
}

Name rule18
Text Numeric constants should be suffixed to indicate type , where an appropriate suffix is
available
Severity Advisory
Description
This rule checks whether a proper suffix is given to a constant that
has been used to give a value to a quantity, which represents a
particular data type. In particular, this technique is used in many
situations to avoid mixing signed and unsigned arithmetic in an
expression.

Example :

int i ,j ;

/* Non-Conforming because - Improper suffix */


int k = 18ul;

/* Non-Conforming because - Improper suffix, 2.0 is treated as


double value */
float l = 2.0;

/* Conforming because - Proper suffix is used here */


float f = 3.0f;
unsigned int m = 10u;

/* Non-Conforming because - Variable m is a unsigned int while


constant 2 is signed */
m = m + 2;
l = 32u + 1.0f; /* Not permitted */
f = 23l + 8.0f; /* Not permitted */
i = j + 3; /* permitted */

Note : ASSENT First determines whether an 'appropriate suffix' is


available by looking at the immediate context in which the constant
occurs. This is then used to determine whether or not a suffix is
required, and if so whether the right one has been supplied.

Name rule19
Text Octal constants (other than zero) shall not be used
Severity Required
Description
Any integer constant that begins with a '0'(zero) is treated as
octal. It is better not to use octal constants at all. Zero is a
special case because strictly speaking '0' is octal zero.

Example :

Array initialisation for 3-digit bus messages would not do as


expected :-
code[1] = 052; /* set to decimal 42 */
code[2] = 071; /* set to decimal 57 */

Name rule20
Text All object and function identifiers shall be declared before use
Severity Required
Description
If an undeclared function is found , the compiler makes an assumption
for the function prototype, based on its use. There is no mechanism to
check this assumption against the actual definition. Hence some
undefined behavior may occur. Therefore, all the functions and objects
should be declared before use.

Example :

/* Function declared here */


int calc();

void func()
{
int a;

/* Non-Conforming because - func2 used without prior


declaration */
func2();
/* Conforming because - calc used after declaration */
a = calc();
}

void main()
{
func();
}

/* Function func2 declared and defined here */


int func2()
{
return 0;
}

/* Function calc defined here */


int calc()
{
return 1;
}

Note : All object and function identifiers, except the function


identifiers in a function call, can only be used after declaration in
ISO-C and this part of the rule is subsumed by Rule 1. Therefore, the
rule only checks for declaration of function identifiers before their
use in a call expression.

Name rule21
Text Identifiers in an inner scope shall not have the same name as an identifier in the outer
scope,and therefore hide that identifier
Severity Required
Description
Hiding identifiers with an identifier of the same name in a nested
scope leads to code which is very confusing.
For example:

SI_16 i ;
{
/* Non-Conforming because - This is a different variable with
same name and making use of i to be confusing */
SI_16 i ;
}

Name rule22
Text Declarations of objects should be at function scope unless a wider scope is necessary
Severity Advisory
Description
As a general principle it is considered good practice to avoid
unnecessarily making identifier global.

Example :
/* Declares max as global */
int max ;

int maximum()
{
int a[5] = { 10,20,30,40,50 };
max = a[0] ; /* max is used here */
return max ;
}

main()
{
/* max not used here,so declare it as local to function
maximum()*/
maximum();
}

Note : This rule is checked by ensuring that all identifiers declared


as file-static or global, are used in at least two functions.

Name rule23
Text All declarations at file scope should be static where possible
Severity Advisory
Description
Declarations at file scope are by default external. Therefore if two
files both declare an identifier with same name at file scope, the
linker will either give an error or identifier will be treated as the
same variable, which may not be what programmer intended. This is also
true if one of the variable is in a library somewhere. Use of the
static storage-class specifier will ensure that identifier are only
visible to the file which they are declared. So if a variable is used
in single file then declare it as static.

Note : This rule is checked by ensuring that all identifiers declared


as global are used in at least two different files.

Name rule24
Text Identifiers shall not simultaneously have both internal and external linkage in the same
translation unit
Severity Required
Description
Identifier shall not simultaneously have internal and external linkage.

Example :

/* Non-Conforming because - This declaration is at file scope and


C-language rules give 'x' internal linkage */
static UI_8 x ;

void foo(UI_16 a)
{
/* Non-Conforming because - This declaration is at block scope
and C-language rules gives 'x' external linkage */
extern UI_8 x ;
}

Name rule25
Text An identifier with external linkage shall have exactly one external definition
Severity Required
Description
This precludes the situations where there is no definition of the
identifier,and where there is more than one definition of the
identifier ( in different files). Multiple definitions in different
files can be a problem even if the definition are same. It is very
serious if the definitions are different or the identifiers are
initialised to different values.

Example:

/* File First.c */

typedef int INT32;


extern INT32 gext;
INT32 gext;

void g (void)
{
gext = 9;
}

/* File Second.c */

typedef int INT32;

/* Non-Conforming because - More than one definition exist */


INT32 gext;

/* Non-Conforming because - There is no definition of b */


extern INT32 b;

Note : As ASSENT Works by analysing source code, it is very likely that


library functions used in the code are not available to be analysed.
Therefore, the tool does not check for definitions of standard library
functions. However, for all other external objects (including functions),
it checks that there exists exactly one definition.

Name rule26
Text If objects or functions are declared more than once they shall have compatible
declarations
Severity Required
Description
It would be wrong, for example, to declare an identifier as being an
int, and to declare the same identifier as also being a float. This
applies whether the object is declared twice in the same file, or
whether an external object is declared differently in two different
files.

Example:

/* File Name file1.c */

typedef int INT32;


extern INT32 i;
extern INT32 j;
void f(void)
{
i = j;
}

/* File Name file2.c */

typedef float FLOAT ;


extern FLOAT i;
void g(void)
{
i = 2.2f;
}

/* File Name file3.c */

typedef int INT32;

/* Non-Conforming because - i is declared as float in file2.c and


int in file1.c*/
INT32 i;
INT32 j;

Name rule27
Text External objects should not be declared in more than one file
Severity Advisory
Description
Each external object should only be declared in a single header file.
The external objects across a program can be declared in one or more
header files. This rule is not concerned with the number of header
files,but with the number of declarations of any one given external
object.

Normally this will mean declaring external objects in header files


which are then included in all those files which use their objects
(including the files which define them).

Example:

/* File: globs.h */
extern SI_16 a;

/* In File1.c */
#include<GLOBS.H designtimesp = 19152
SI_16 a;
.....

/* In FIle2.c */
#include<GLOBS.H designtimesp = 19153
SI_16 a;
.....

'extern SI_16 a' declaration is repeated in File1.c and File2.c


Therefore rule27 is violated in above case because of #include<GLOBS.H designtimesp
= 19154,
extern SI_16 is repeated in multiple files.

Name rule28
Text The register storage class specifier should not be used
Severity Advisory
Description
ISO compilers are not obliged to take any notice of the register
storage class specifier,so at best it is only a hint to the compiler.
A good optimiser should be able to decide for itself what to put in
registers.

Example:

typedef int INT32;


INT32 main (void)
{
/* Non-Conforming because - register storage class specifier
used */
register INT32 j;
INT32 k;
j = 12;
return 0;
}

Name rule29
Text The use of a tag shall agree with its declaration
Severity Required
Description
Where a tag has been given in the declaration of an enumeration ,
structure or union type, all subsequent uses of the tag shall be
consistent with the declaration. For example, it would be incorrect
to initialise the tag with an initialiser which did not match the
structure declaration for the tag.

Example:

typedef int INT32;


typedef char CHAR;

void f(void)
{
struct first
{
INT32 a;
CHAR b;
};

struct second
{
INT32 a[10];
struct first new;
};

enum colour {red,green,blue};

struct first right = { 1, 'a'};

/* Non-Conforming because - Since 1 is assigned to CHAR


datatype*/
struct second wrong = { {1,2,3,4,5,6,7,8,9,10}, {1,1}};

enum colour watch = 1;

Note : This rule is one of the less clearly specified rules in the
guidelines. It only states that the use of a 'struct' or 'enum' tag
shall agree with its declaration.
ASSENT checks that the initialisation of an object of struct or enum
type is consistent with the declared structure.

Name rule30
Text All automatic variables shall have been assigned a value before being used
Severity Required
Description
The intent of this rule is that all variables should be written to
before they are read. This does not necessarily require
initialisation at declaration, although that is one way of achieving
the intent.

Example:

typedef int INT32;

INT32 main(void)
{
INT32 i,j,k;
INT32 *p;

i = 12;

/* Non-Conforming because - k is being used without


initialization. */
j = i + k;

/* Non-Conforming because - p is being used without


initialization. */
k = *p;

return 0 ;
}

Note : ASSENT checks this rule conservatively to ensure that all


automatic variables have a value assigned before any usage. By
conservative, it is meant that non-compliance is reported if there is
any path along which the variable does not get a value before being
used, though such a path may not actually be taken in any given
execution of the program.

The rule checks that automatic variables are initialised only in parts
of the code which are reachable during execution. Usage of
uninitialised variable in unused parts of code(such as functions which
are never called)are not reported.

The tool does not catch usage of uninitialised locations of the heap.
However, as a consequence of rule 118, it is unlikely to cause problems
in MISRA-C conformance checking.

Name rule31
Text Braces shall be used to indicate and match the structure in the non-zero initialisation of
arrays and structures
Severity Required
Description
ISO-C requires initialiser lists for arrays, structures and union
type to be enclosed in a single pair of braces. This rule further
requires the use of additional braces to indicate nested structures.

Example :

/*Non-Conforming because - Braces not used to match the structure


of array*/
INT32 Arr[3][2] = { 1, 2, 3, 4, 5, 6 };

/* Conforming because - Proper braces are used*/


INT32 Arr[3][2] = { {1, 2}, {3, 4}, {5, 6} };

A similar principle applies to structures, and nested combinations of


structures, arrays and other types.

Name rule32
Text In an enumerator list , the '=' construct shall not be used to explicitly initialise members
other than the first , unless all items are explicitly initialised
Severity Required
Description
An explicit initialisation of the first element, as permitted by
above rule, forces the allocation of the integers to start at the
given value. Explicit initialisation of all items in the list, which
is also permissible, prevent the mixing of the automatic and manual
allocation.
Example :

void f(void)
{
/* Conforming because - None of the members are initialized*/
enum corren {red,blue,green} ;

/* Conforming because - Only first member is initialized */


enum firstinitenum {al=7,sir,aja} ;

/* Conforming because - All members are initialized */


enum allinitenum {m = 3, f = 4, c = 5, e = 6} ;

/* Non-Conforming because - Mixing of the automatic and manual


allocation. */
enum wr1enum {old = 2, young, middle = 9} ;

/* Non-Conforming because - Either all or none of the members


are initialized */
enum wr2enum{dog, cat = 9 , ass} ;

/* Non-Conforming because - Either all or none of the members


are initialized */
enum wr3enum{orange, mango, guava = 10} ;

Name rule33
Text The right hand operator of a && or || operator shall not contain side effects
Severity Required
Description
There are some situations in C code where certain parts of expressions
may not be evaluated. If these sub-expressions contain side effects
then those side effects may or may not occur,depending on the values
of other sub-expressions.The operators which can lead to this problem
are '&&' ,'||' and '?:'

In the case of '&&' and '||' the evaluation of right hand operand is
conditional on the value of the left-hand operand. In the case of '?:'
operator,either the second or third operands are evaluated but not both.

Example :

if ((i == j) && (a[j++]))


/* Here j++ will be executed only if i == j is true */

if ((i == j) || ( g(j) ))
/* Here g(j) function may cause side-effect to j and it would be
only when i == j is false and hence should be avoided */

Note : This rule is followed exactly by ASSENT Where an expression


with a side-effect is as defined in the 'Definitions' section.
Name rule34
Text The operands of a logical && or || shall be primary expressions
Severity Required
Description
Primary expressions is either a single identifier or the constant or
the paranthesised expression. If an operand is other than a single
identifier or constant then it must be paranthesised. Paranthesis is
required for read-ability of code and for ensuring that the behaviour
is as intended by the programmer.

Example :

/* Non-Conforming because - i+j should be in parenthesis otherwise


expression looks ambiguous */
if (2 || i + j )

/* Non-Conforming because - behaviour of code may not be same as


programmer's intension. */
if ( i == j && (j == 2) )

Name rule35
Text Assignment operators shall not be used in expressions which return Boolean values
Severity Required
Description
There is a conceptual difference between expressions which return a
numeric value and expressions which return a Boolean value. If
assignments are required then they must be performed separately
outside of any expressions which are effectively of Boolean type.

If the Boolean expression is a logical or relational expression then


the rule does not allow the expression's operand(s) to be assignments.

If the expression is a conditional expression then the rule does not


allow the expression to be an assignment expression.

This precludes expressions of the form:


((a = b) && c) and statements of the form: if (a == b)

Example:

(i = 2) ? j : k;

/*Here 'i=2' expression must return true or false where as


here it always return true.So assignment is performed where
evaluation is expected.*/

while (i = 2)

/*Here 'i=2' will also cause expression to be always true and


assignment during evaluation of expression.*/

{
j++;
}

Similarly following 'if' and 'for' statement

if( i = 2)
/* 'i = 2' will assign 2 to 'i' */

for(i = 0 ; (i < 4) || (i = 2) ; i++)


/* 'i' will always turn to be 2 and is not what should be.*/

Name rule36
Text Logical operators should not be confused with bit-wise operators
Severity Advisory
Description
The logical operators '&&', '||' and '!' can be easily confused with
the bitwise operators '&','|' and '~'. A logical operator is any
operator that appears in a conditional expression. The rule does not
allow such logical operators to be one of the bit-wise operators,
namely '&', '|' and '~'.

Example:

/*Non-Conforming because : Here '&' may not be put by mistake*/


b = (a & b) ? a : b ;

/*Non-Conforming because : Here a | b may have been put by


mistake. It would be more meaningful with a || b */
if (a | b)

/* Non-Conforming because : Here '~' is confused with '!' */


while( ~a)
{...}

Name rule37
Text Bitwise operations shall not be performed on signed integer types
Severity Required
Description
Bit-wise operations(~,<<,>>,&,^ and |) are not normally meaningful
on signed integers.Problems can arise if,for example, a right shift
moves the sign bit into a number, or a left shift moves a numeric bit
into the sign bit.

Example:

signed int SINT;


typedef int INT32;
typedef unsigned int UINT;

INT32 main(void)
{
SINT i = 0;
SINT j = 0,g = 0;
UINT k = 0u;
INT32 l = 0;

/* Non-Conforming because : 'i' is signed.*/


g = i & j;

/* Non-Conforming because : 'k' is signed*/


g = ~k;

/* Non-Conforming because : 'l' is signed.*/


g = ~l;

/* Conforming because : function fun() returns unsigned int


and there would not be any change in constant literal 8.*/
k = fun() << 8 ;

return 0 ;
}

Name rule38
Text The right hand operand of a shift operator shall lie between zero and one less than the
width in bits of the left hand operand (inclusive)
Severity Required
Description
If the left hand operator of a left-shift or 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.This rule is checked exactly by ASSENT,
subject to limitations of statically determining the value of the
right hand operand of a shift operator.If the right-hand operator is
a constant, then the tool works only if it is a decimal constant.If
it is an expression, then the tool attempts to determine if the value
of the expression is always a constant through a constant-propagation
analysis. It checks the shift expression for conformance only if it
can determine that the expression is a constant.

Example:

typedef int INT32;


typedef short SHORT;

INT32 i;
SHORT j;

/*Here i occupies 32 bits(for unix)*/

/*Non-Conforming because : 32 bit data field is shifted 40 bits.*/


i >> 40u;

/*Non-Conforming because :j occupies 16 bits and shifted by 33


bits.*/
j << 33u;
Name rule39
Text The unary minus operator shall not be applied to an unsigned expression
Severity Required
Description
It is not meaningful to apply a unary minus operator to an unsigned
expression except in a mixed signed/unsigned expression(which itself
should be avoided)

Example:

typedef int INT;


typedef unsigned int UINT;

INT main(void)
{
INT i = 0,j = 0,k = 0;
UINT x = 0u, y = 0u, z = 0u;

i = -j;

/* Non-Conforming because : x is unsigned and '-' is applied


to it.*/
i = -x;

/* Non-Conforming because : x+i is a mixed operation and


should be avoided*/
j= -(x+i);

/* Non-Conforming because : x+y is unsigned expression and


'-' operator should be avoided */
k= -(x+y);

return 0;
}

Name rule40
Text The sizeof operator shall not be used in expressions that contain side effects
Severity Advisory
Description
A common programming error in C is to apply the sizeof operator to
an expression and expect the expression to be evaluated.However the
expression is not evaluated: sizeof only acts on the type of the
expression. To avoid this error,sizeof should not be used on
expressions which contain side effects,as the side effects will not
occur.

Example:

typedef unsigned int INT32;

static INT32 glb = 2u;


INT32 g1 (void) { glb++; return 0u; }
INT32 g (INT32 k) { return k*9u; }

/* Non-Conforming because : operand for sizeof operator is


expression and this expression is not evaluated.*/

j = sizeof (i = 1u);
j = sizeof (i);

/* Non-Conforming because : operand for sizeof operator is


function call and g() will not be called*/
j = sizeof (g1 ());
}

Name rule42
Text The comma operator shall not be used except in the control expression of a for loop
Severity Required
Description
Use of the comma operator in situations other than the control
expression of a 'for' loop is generally detrimental to the readability
of code,and the same effect can be achieved by other means.

Example:

j++, i++;
Such use of comma operator should be avoided

Name rule43
Text Implicit Conversions which may result in loss of information shall not be used
Severity Required
Description
C performs many types conversions implicitly and silently, so as to
harmonize types within an expression before evaluating it. Some of
these conversion can result in loss of information(eg. conversion to
a narrower type).Such implicit conversions shall not be used, but
explicit casts should be used instead.

This rule ensures that both the operands of all binary expressions
have the same type (modulo type qualifiers such as const and
volatile). Similarly it also checks :
* The 'then' and 'else' operands of a ternary expression having
the same type.
* The declared parameter type and actual type of all parameters
in a call expression have the same type
* An initialization expression and the initialized identifier
have the same type.

Note that for function calls, the rule is checked against the
definition of the function, if available, else it is checked against
its declaration.

Example:
typedef int INT;
typedef float FLOAT;
typedef short SHORT;

INT con(FLOAT);

void f(void)
{
/* short type is assigned to an integer type identifiers */
INT a = 10, b = 20, c = 30 ;
FLOAT x = 3.0f, y = 2.0f, z = 1.0f;
INT *point = 10;

/* The right hand side may results in implicit conversion */


x = a/b;

/* Implicit conversion between identifier 'z' and 'a' */


y = x*(z/a);

/* operation is performed on float and a integer pointer */


*point = *point + x;

/* Implicit conversion between then and else part of ternary


expression */
a = (b<c) ? a : y;

/* Implicit conversion takes place between actual and formal


parameters */
c = con(b);
}

INT con(FLOAT d)
{
return (INT)d;
}

Name rule44
Text Redundant explicit casts should not be used
Severity Advisory
Description
Explicit casting between identical types is unnecessary and it
clutters the code. Furthermore it can mask problem if changes are
made to the code. The use of casting should be sufficient to cause
the calculation required to occur with the desired precision.
Unnecessary casting adds the possibilities of confusion, and may also
lead to form a code which is harder to maintain, should the types of
variables change.

Example:

typedef short int SINT;

SINT f(void)
{
return 3;
}

void h(void)
{
SINT i = 0, k = 0;
/* Non-Conforming because - Type casting to i is redundant*/
k=(SINT)i;

k = (SINT)f();
/*Unnecessary casting of function f() return type */
}

Name rule45
Text Type casting from any type to or from pointers shall not be used
Severity Required
Description
Pointer types shall not be cast to other types including pointer
types. Other types also should not be cast to pointers. This can lead
to undefined or implementation-defined behaviour, and it also
circumvents types integrity.

For example : Problems can arise if

* A pointer can converted to an integer type which is not large


enough to hold the value.
* An arbitrary integer is converted to a pointer.
* A pointer to an object is converted to a pointer to a
different type of object.

Pointer to pointer conversion can also provide an unauthorised means


of writing to a 'const' qualified object.

Example:

typedef int INT;


typedef float FLOAT;
INT *func(INT *k)
{
INT *ptr = k;
return ptr;
}

INT main(void)
{
INT *i = 0;
FLOAT *j = 0;
INT k=2;
FLOAT l=1.2f;

/*Non-Conforming because - Floating point pointer is cast to


integer type */
j = (FLOAT *)i;
/*Non-Conforming because - cast to integer type */
(INT *)(j++)

/*Non-Conforming because - Function func return integer


pointer which is cast to float */

j = (FLOAT *)func((INT *)j);

return 0 ;
}

Name rule46
Text [Req] The value of an expression shall be the same under any order of evaluation that
the standard permits
Severity Required
Description
Apart from a few operators except function call operator (),'&&',
'||','?:' and the order in which subexpressions are evaluated is
unspecified and can vary.

The value of an expression depends on its evaluation order if and


only if:

1. Any of its operands depends on its evaluation order

2. The expression is a binary expression but not a short-circuit


'&&' or '||' expression and
* The same value is either being modified more than once
in the expression or
* The same value is being modified and used or
* The same volatile value is being used more than once
in
the expression.

3. The expression is a unary increment/decrement operator and the


value being incremented/decremented is also being modified in the
operand.

4. The expression is an array-index or function-call expression


and the same value is either being modified more than once or
being both modified and used in the array-expression (function
expression) and or the index (parameter) expressions.

Example:

volatile INT32 vi = 0,*vj = 0;


/* Conforming because - proper usage for increment and
decrement operators */
x = b[i] + i;
i++;

/* Conforming because - proper usage for functions call */


x = f(i);
x = x + g(i);

/* Conforming because - proper usage for nested assignment


statements */
i = x/3;
x=f(i)

/* Conforming because - proper usage for accessing a volatile */


x = vi;

/* Non-Conforming because - improper usage for increment and


decrement operators */
x = b[i] + i++;

/* Non-Conforming because - improper usage for functions call */


x = f(i) + g(i);

/* Non-Conforming because - improper usage for nested assignment


statements */
x=f(i = x/3);

/* Non-Conforming because - improper usage for accessing a


volatile */
x = vi + *vj;

Name rule47
Text No dependence should be placed on C's operators precedence rules in expression
Severity Advisory
Description
When an expression contains several operators,parenthesis should be
used to override default operator precedence.Using paranthesis makes
the code easier to read and avoid errors.An expression is said to pass
this rule only if all binary and unary operands of a binary expression,
which is not one of the assignment expressions, are parenthesized.

Example:

d = (a / b) * c ; /*Conforming code */
d = a / (b * c); /*Conforming code */
d=a+b; /*Conforming code - Paranthesis not
required*/
d = a / b * c; /*Non-Conforming code - Paranthesis required*/

Name rule48
Text Mixed precision arithmetic should use explicit casting to generate the desired result
Severity Required
Description
In an expression, sub-expressions are evaluated at the precision
appropriate to the types of the operands. This may be less than the
precision of the final result. Therefore a check is to be performed.

This rule checks that if any expression involves operands of primitive


types only, then either both operands have the same precision or the
operand with the smaller precision is atomic, so that no computation
occurs in the wrong precision.

Example:

typedef int INT32;


typedef float FLOAT;
INT32 i = 1 , j = 3;
FLOAT f1, f2;

f1 = FLOAT i / j; /* Conforming case - f1 = 0.333 */


f2 = (FLOAT)i/(FLOAT)j; /* Conforming case - f2 = 0.333 */

f1 = i / j; /* Non-Conforming
case - f1 = 0.0 */
f2 = (FLOAT)(i / j); /* Non-Conforming case - f2 = 0.0 */

Name rule49
Text Tests of a value against zero should be made explicit , unless the operand is effectively
boolean
Severity Advisory
Description
When a data value (except Boolean )is to be tested against zero then
the test should be made explicit. This rule makes the clear
distinction between integers and logical values.

Example:

/* Conforming because - Test against zero is done explicitly */


if (x != 0)
{
/* something */
}

/* Non-Conforming because - x is not boolean */


if (x)
{
/* something */
}

Name rule50
Text Floating point variables shall not be tested for exact equality or inequality
Severity Required
Description
Comparisions of equality of floating point types will often not
evaluate to true even when they are expected to.The behaviour of such
a comparision cannot be predicted before execution,and may vary from
one implementation to another.

Example:
typedef float F_32;
F_32 x, y;

if(x == y) /* Non-Conforming because - Float variables is being


tested for exact equality */
{
/* something */
}

Name rule51
Text Evaluation of constant unsigned integer expressions should not lead to wrap-around
Severity Advisory
Description
Unsigned integer expressions do not strictly overflow,but instead
wrap around in a modular way.This rule detects any constant unsigned
integer expression which in effect 'overflow' not caught by the
compiler.

Example:

typedef unsigned int UINT;


typedef const unsigned int CUINT;
UINT i, r;
CUINT d;
CUINT c;

d = 400;
c = 450;
r = 4u - 9u; /* Non-Conforming because - Unsigned int is given
a signed value*/
i = d - c; /* Non-Conforming because - Unsigned int is given
a signed value*/
i = 3000000000u + 3000000000u;
/* Non-Conforming because - i
would get value out
of range*/

Name rule52
Text There shall be no unreachable code
Severity Required
Description
This refers to a code which cannot be reached under any circumstances
and which can be identified as such during compilation. Code which can
be reached but never be executed is excluded from the rule
(eg. defensive programming code).
Example:

/*Conforming code*/

typedef int INT32;

/* Something */
switch (ival % 3)
{
case 0: /* something */ break;
case 1: /* something */ break;
case 2: /* something */ break;
default:
/* Handle negative value of i */
break;
}

/*Non-Conforming code*/

typedef int INT32;


enum Color { RED, GREEN, BLUE };

enum Color ink = RED;


INT i = 1;
if(1)
{
/* something */
}
else
{
/* Non-Conforming location */
}
switch(ink)
{
case RED:
break;
ink = GREEN; /* Non-Conforming location */
case GREEN:
ink = RED;
break;
case BLUE:
break;
default: /* Non-Conforming location */
break;
}

goto l;
i = 3; /* Non-Conforming location. */
l:
switch (i)
{
i = 2; /* Non-Conforming location. */
case 2 : break;
default : break;
}
INT g (void)
{
for(k = 0; ; )
{
;
}
k = k*2; /* Non-Conforming location */
}
Name rule53
Text All non-null statements shall have a side effect
Severity Required
Description
The occurrence of statements (other than null statements) which have
no side-effect will normally indicate a programming error, and
therefore a static check for such statements shall be performed.

Example:

/*Non-Conforming code*/

typedef int INT;

static INT glb;

void g (INT i)
{
glb = i;
}

void f (INT i,INT j)


{
i=j++;
j=i*j;
}

void h (INT *p)


{
*p = 2;
}

void f1(INT i,INT j)


{
i=j*3;
!(i==2); /* Non-Conforming location */
f (i, j); /* Non-Conforming location */
g (i);
for (i*2;i<9;) /* Non-Conforming location */
{
;
}

h (&i);

switch(i)
{
case 1 : break;
case 2: i+j; /* Non-Conforming location */
default : break;
}

switch(i) /* Non-Conforming location */


{
case 1 : break;
case 2: ;
default : break;
}

switch(++i)
{
case 1 : break;
case 2: ;
default : break;
}

for(i=0;i<10;i++);

for(;i<10;i+j) /* Non-Conforming
location */
{
;
break ;
}

while(i+j) /* Non-Conforming location */


{
;
}

while(++i)
{
;
break ;
}

return;
}

INT main(void)
{
INT a = 2, b = 3;
f1(a,b) ;

return 0 ;
}

Name rule54
Text A null statement shall only occur on a line by itself, and shall not have any other text on
the same line
Severity Required
Description
Normally null statements should not be deliberately included, but
wherever they are used they should appear on a separate line by
themselves and not with any other text (including comments).

Example :
/*Non-Conforming code*/

if(i==j) ; /* null stmt with IF */

/*Conforming code*/

if(i==j)
;
/* Null stmt on Separate line */

Name rule55
Text Labels shall not be used except in switch statements
Severity Advisory
Description
Normally the use for labels, other than in switch statements, is as
targets for the 'goto' statements, which is prohibited by Rule 56.
Example:

/*Non-Conforming code*/

typedef int INT;


void f1(INT i, INT j)
{
all : /* Non-Conforming location */
i=j*7;
switch(i)
{
case 1 : i=1;
break;
default : i++;
}
return;
}

Name rule56
Text The goto statement shall not be used
Severity Required
Description
Example:

/*Non-Conforming code*/

typedef int INT;

void f1(INT i,INT j)


{
if ((i<4))
{
goto all ;
}
all :
i=j*7;
return;
}

Name rule57
Text The continue statement shall not be used
Severity Required
Description
Example:

/*Non-Conforming code*/

typedef int INT;


void f1 (INT i, INT j)
{
for (i=j; i < j; i++)
{
j=j*2;

if (i>100)
{
continue;
}
}
}

Name rule58
Text The break statement shall not be used except to terminate the cases of a switch
statement
Severity Required
Description
Example:

/*Non-Conforming code*/

typedef int INT;


void f1(INT i,INT j)
{
while (i!=j)
{
break ;
}
switch(i)
{
case 1 : i=1;
break;
case 2: i=2;
break;
i = 3;
default : i++;
}
return;
}
Name rule59
Text The statements forming the body of an if, else if, while, do-while and for shall always be
enclosed in braces
Severity Required
Description
The statements forming the body of an if,else if,while,do-while and
for should always be enclosed in braces even if they are single
statements. This avoids the danger of adding code which is intended
to be part of the conditional block but is actually not.

Example:

/*Conforming code*/

typedef int INT32;


INT32 test=2,x=4;
if(test!=0) /* if is in braces */
{
x++;
}
else /* else is in braces */
{
x--;
test++;
}

/*Non-Conforming code*/

typedef int INT32;


INT32 test=2,x=4;
if(test!=0) /* if is not in braces */
x++;
else /* else is not in braces */
x--;
test++;
/*test++ is not considered as part of else but it should be */

Name rule60
Text All if, else if constructs should contain a final else clause
Severity Advisory
Description
This rule applies for all if-else-if constructs. If it is a simple if
statement then the else statement need not be included.The requirement
for a final else statement is defensive programming.The else statement
should either take appropriate action or contain a suitable comment as
to why no action has been taken.
Example:

/*Conforming code*/

typedef int INT32;


INT32 x;
if(x!=0) /* Simple if statement.Else statement need not be
included */
{
/* Something */
}

if(x < 0) /* if-elseif constructs should include final else*/


{
/* Something */
}
elseif(x > 0)
{
/* Something */
}
else
{
/* Something */
}

/*Non-Conforming code*/

typedef int INT32;


INT32 x;
if(x!=0) /* Simple if statement.Final else clause
is not needed */
{
/* Something */
}

if(x < 0) /* if-elseif construct not having a final


else clause */
{
/* Something */
}
else if(x > 0)
{
/* Something */
}

Name rule61
Text Every non-empty case clause in a switch statement shall be terminated with a break
statement
Severity Required
Description
Normally each 'case', when executed,will fall through to the code of
the next case. The use of break statement at the end of each case
clause causes just the code of that clause to get executed.

Example:

/*Conforming code*/

typedef int INT32;


INT32 x=0;
switch(x)
{
case 0: /* something */
/* Nonempty case followed by break */
break;

case 1:
/* Empty case.No break is required */
case 2:/* something */
break;
default:/* something*/
}

/*Non-Conforming code*/

typedef int INT32;


INT32 x=0;
switch(x)
{
case 0:/* something */
/* Nonempty case not followed by break */
case 1:
case 2: /* something */
break;
default: /* something*/
}

Name rule62
Text All switch statements shall contain a final default
Severity Required
Description
The requirement for a final default clause is defensive programming.
This clause should either take an appropriate action or contain a
suitable comment as to why no action has been taken.

Example:

/*Conforming code*/

typedef int INT32;


INT32 x=1;
switch(x)
{
case 0: /* something */
break;
case 1: /* something */
break;
default:/*something */ /* default clause is required */
}

/*Non-Conforming code*/

typedef int INT32;


INT32 x = 1;
switch(x)
{
case 0: /* something */
break;
case 1:/* something */
break;
}

Name rule63
Text A switch expression should not represent a Boolean value
Severity Advisory
Description
Boolean data can take only two values. Instead of using Switch,
If-else construct can be used.It is a better way of representing two
way choice.
Example:

/*Conforming code*/

typedef int INT32;


INT32 flag=0; /* flag will contain only boolean values */
if(flag==0) /* Instead of using switch use if-else*/
{
/* something */
}
else
{
/* something */
}

/*Non-Conforming code*/

typedef int INT32;


INT32 flag = 0;
/* flag will contain only boolean values */

switch(flag) /* switch should not be used */


{
case 0: /* something */
break;
case 1:/* something */
break;
}

Name rule64
Text Every switch statement shall have at least one case
Severity Required
Description
Example:

/*Conforming code*/
typedef int INT32;
INT32 x=1;
switch(x) /* switch having atleast one case */
{
case 1:/* something */
break;
default:/* something */
}

/*Non-Conforming code*/

typedef int INT32;


INT32 x=1;
switch(x)
{

Name rule65
Text Floating point variables shall not be used as loop counters
Severity Required
Description
A 'loop counter' is one whose value is tested to determine
termination of the loop. Floating point variable should not be used
for this purpose. Rounding and truncation errors can be propagated
through the iteration of the loop, causing significant inaccuracies
in the loop variable.

Example:

/*Non-Conforming code*/

typedef int INT;


typedef float FLOAT;
typedef double DOUBLE;

void f (INT i, FLOAT d)


{
INT i1 = 0,i2 = 0,i3 = 0;
FLOAT fl1 = 0.0f, fl2 = 0.0f;
DOUBLE db1 = 0.0, db2 = 0.0;
DOUBLE *p = 0;
FLOAT ff = 0.0f;

while (d < 23.0f)


{
i++;
}

for (i1 = 0 ; i1 < i ; i1++)


{
;
}
for (i3 = 0; (i2 < 4) && (i3 > db2) ; i3++)
{
;
}

p = &db1;

for (i2 = 0; (i2 < 4) && (*p > i1) ; i2++)


{
;
}

for(i1 = 0; (i2 < 4) && (fl2 > i1) ; i1++)


{
;
}
return;
}

Name rule66
Text Only expressions concerned with loop control should appear within a for statement
Severity Advisory
Description
Loop control of 'for' statements should contain only the concerned
expressions.

Example:

/*Conforming code*/

typedef int INT;

void f(INT i, INT j)


{
INT k,l ;

for (i = 0, j = 0 ; i < j ; i++, j+=5)


{
;
}

for ( ; i < 10; )


{
i++;
}

for (i = j+9 ; i < 14 ; i+=j)


{
;
}
}

/*Non-Conforming code*/
typedef int INT;

void f(INT i, INT j)


{
INT k,l ;

for (i = 0, j = 0; i < 10; i++)


{
;
}

for (i = 0;i < 10; i++,j++)


{
;
}

for ( ; i < 10; j++)


{
i++;
}
}

Name rule67
Text Numeric Variables being used within a for loop for iteration counting should not be
modified in the body of the loop
Severity Advisory
Description
The only expressions within a 'for' statement should be to
initialise, increment (or decrement)and test loop counter(s) and to
test other loop control variables. These loop control variables
should not be modified in the body of the loop.

Example:

/*Conforming code*/

typedef int INT;

void f(INT i, INT j)


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

for ( ; i < 10; )


{
i++;
}
}

/*Non-Conforming code*/
typedef int INT;
void f(INT i, INT j)
{
INT k = 0,l = 0 ;
INT *ptr = &j ;

for (i = 0, j = 0; i < j; i++,j+=5)


{
*ptr = 10;
}

for(i = 0, j = 0; i < j; i++,j+=5)


{
j = 10;
}

for (i = 0, j = 0; i < 10; i++)


{
i += 10;
}
}

Name rule68
Text Functions shall always be declared at File scope
Severity Required
Description
Declaring functions at block scope may be confusing, and can lead to
undefined behaviour.

Example:

/*Non-Conforming code*/

typedef int INT;

void g (void)
{
extern INT h (INT i);

INT f (INT);
}

Name rule69
Text Functions with variable number of arguments shall not declared or defined
Severity Required
Description
This rule checks for function having variable number of arguments
either declared or defined. Undeclared function is also treated as
variable argument function in ANSI-C.

Example:
/*Non-Conforming code*/

typedef int INT;

INT func (INT c, ...);

INT g ();

INT func (INT c, ...)


{
INT b = 10;
calc();
return c + b;
}

Name rule69a
Text Functions with variable number of arguments shall not declared or defined
Severity Required
Description
This rule check for function having variable number of arguments either decl-
ared or defined. Undeclared function is also treated as variable argument func-
tion in ANSI-C.

Example:

typedef int INT;


INT func (INT c, ...); /* Declared here */
INT g (); /* Declare it
as g(void) */

INT func (INT c, ...) /* Defined here */


{
INT b = 10;
calc(); /*
Undecleared function */
return c + b;
}

Name rule69b
Text Functions with variable number of arguments shall not be called
Severity Required
Description
This rule check for function call having variable number of arguments either
declared or defined.Note that undeclared functions also are treated as variable
functions in ANSI-C.

Example:

typedef int INT;

INT func (INT c, ...);

INT func (INT c, ...)


{
return c + b;
}
INT f (void)
{
INT a = 0, b = 0, c = 1, d = 1;
INT (*fp)(INT, ...);
INT (*gp)();

b = g (); /* Undeclared function


*/
a = func(a,b); /* Variable arguments */

gp = &g;
fp = &func;

a = (*fp)(c, d); /* Call through function pointer */


b = (* gp)(); /* Call through function
pointer */

return 0;
}

Name rule70
Text Functions shall not call themselves directly or indirectly
Severity Required
Description
This means that recursive function calls can not be used in safety-
related systems. Recursion carries with the danger of exceeding
available stack space, which can be a serious error. Unless recursion
is very tightly controlled, it is not possible to determine before
execution what the worst case stack usage could be.

Note: In this version of Assent, recursive calls through function


pointers are not detected. All other recursion is detected.

Name rule71a
Text Functions shall always have prototype declarations and the prototype shall be visible at
function definition
Severity Required
Description
Functions should always have prototype declarations and the prototype
shall be visible at function definition.

Example :

void sally(void);

/* Conforming because - Function prototype is visible at this


definition */
void sally()
{
}

/* Non-Conforming because - No visible declaration at this


definition */

void sallysansProto()
{
}

Name rule71b
Text Functions shall always have prototype declarations and the prototype shall be visible at
the function call
Severity Required
Description
Functions should always have prototype declarations and the prototype
should be visible at the function call.

Example :

typedef int INT;


void sally(void);

void sally()
{
}

INT main (void)


{
/* Conforming because - Function prototype is visible at the
function call */

sally ();

/* Non-Conforming because-Function has no visible declaration


at this call */

headerFunc(10);

return 0;
}

Name rule72
Text For each function parameter the type given in the declaration and definition shall be
identical , and the return type shall also be identical
Severity Required
Description
For each function parameter the type given in the declaration and
definition should be identical , and the return type should also be
identical.

Example:
/* In header file */

extern void h (void); /* Non-Conforming because - return types


mismatch */

/* In Source file */

typedef int INT32;

INT32 h (void)
{
return 0;
}

Name rule73
Text Identifiers shall be given for all the parameters in a function prototype declaration or for
none
Severity Required
Description
Identifiers should be given for all the parameters in a function
prototype declaration or for none.

Example:

typedef int INT32;

/* Non-Conforming because - Identifier name not given for first


paramater */

void f1(INT32 , INT32 i2);

Name rule74
Text If identifiers are given for any of the parameters then the identifiers used in the
declaration and definition should be identical
Severity Required
Description
If identifiers are given for any of the parameters then the
identifiers used in the declaration and definition should be
identical.

Example:

typedef int INT32;

/* Non-Conforming because - Identifiers name mismatches */

INT32 funct(INT32 k);

INT32 funct(INT32 i)
{
return 0;
}
Name rule75
Text Every function shall have an explicit return type
Severity Required
Description
Functions should always be declared with a return type, that type
being void if the function does not return data.

Example:

typedef int INT32;


void myfunc(void);

/* Conforming because - Return type is void */


void myfunc(void)
{
}

/* Non-Conforming because - Explicit return type is not given*/


mysecfunc(INT32 a)
{
return 0;
}

Name rule76
Text Functions with no parameters shall be declared with parameter type void
Severity Required
Description
Functions with no parameters should be declared with parameter type
void.

Example:

/* Non-Conforming because - It should have an explicit 'void'


parameter */

void myfunc();

Name rule77
Text The unqualified type of parameters passed to a function shall be compatible with the
unqualified expected types defined in the function prototype
Severity Required
Description
This rule permits the types of parameter and prototype to differ in
type qualification. This is intended to permit the use of 'const'
qualification. In other words,for example,an int variable can be
passed as a parameter defined in the function prototype to be int or
const int,but not as a parameter declared to be long.

Example:
/* Non-Conforming Code */

typedef int INT32;


typedef long int LONG;
typedef double DOUBLE;
void g0 (INT32 k);
void g1 (INT32 i);
void g2 (const INT32 ci);

void f (void)
{
INT32 i = 2;
const INT32 ci = 2;
LONG l = 2L;
const LONG cl = 2L;
DOUBLE d = 2.9;

g0(d);

g1 (l);

g2 (cl);

g2 (l);
}

Name rule78
Text The number of parameters passed to a function shall match the function prototype
Severity Required
Description
The function call should comply with the function prototype in terms
of the number of parameters and their types.

Example:

/* Non-Conforming Code */

typedef int INT32;


INT32 f (INT32 i, INT32 j);
INT32 g1 (INT32);
INT32 main (void)
{
INT32 (* fp4)();
INT32 (* fp3[2])();

(*fp4) (2, 3);

(*fp4) (3);

(fp3[0]) (2, 3);


(*fp3[0]) (3);

(*f) (2, 3);


return 0;
}

INT32 f(INT i,INT j)


{
/* Something */
}
INT32 g1(INT i)
{
/* Something */
}

Name rule79
Text The values returned by void expressions shall not be used
Severity Required
Description
The usage of values returned by void functions results in a void
expression,the behaviour of which is undefined.

Example:

void f (void);

/* Non-Conforming because - function f return type is void */


if (f ())
{
}

Name rule80
Text Void expressions should not be passed as function parameters
Severity Required
Description
Void expressions should not be passed as function parameters because
this can leave the lvalue undefined and behaviour may be
unpredictable.

Example:

typedef int INT32;


INT32 f (INT i);

void g (void);

/* Conforming because - function parameter passed is not a void


expression */

f (f (2));

/* Non-Conforming because - void expression passed as a function


parameter */
f (g ());

Name rule81
Text const qualification should be used on function parameters which are passed by
reference, where it is intended that the functions shall not modify the parameter
Severity Advisory
Description
This rule helps to prevent the modification of the function parameter
which is intended as input parameter only. So if a function parameter
is not modified in the function definition and is also not declared as
const in the function prototype, deemed a violation to this rule.

For Example:

typedef int INT;

INT sort (const INT *CIP,INT *IP, INT *IP1, INT k)


/* Non-Conformance for IP1 variable */
{
*IP1 = 2;
return 0;
}

INT main (void)


{
const INT *cip = 0;
INT i = 0, j = 0, k = 0;
INT *ip = &j;
INT *ip1 = &k;
k = sort (cip, ip, ip1, i);
return 0;
}

Name rule82
Text A function should have a single point of exit
Severity Advisory
Description
This rule means that a function will normally have a single exit at
the end of the function. The exit points of a function are defined to
be all implicit or explicit returns from the function or direct calls
to one of the library functions exit or longjmp. Given this
definition of exit points from a function ,the tool checks this rule
exactly.

For Example:

void f (void) /* Non-Conformance Location */


{
if (2 > 3)
{
return;
}
else
{
int i = 2;
i ++;
return;
}
return;
}

Name rule83
Text For functions with non-void return type (i) there shall be one return statement for every
exit branch including the end of the function, (ii) each return shall have an expression,
(iii) the return expression shall match the declared return type
Severity Required
Description
The absence of return with an expression leads to undefined behaviour
for which the compiler may not give error. This rule is to check for
functions that have non-void return type. Every exit point must use a
return statement and each return statement within the function must
have an expression of the type of the function.

For Example:

typedef int INT;

INT f1 (INT i) /* Non-Conformance Location */


{
if (i > 2)
{
return 0;
}
else
{
return;
}
}

Name rule84
Text For functions with void return type , return statements shall not have an expression
Severity Required
Description
If any return statements are used in a function that returns a void
type, expressions should not be placed after the return.

For Example:

void f (void)
{
if (2 > 3)
{
return;
}
else
{
return 2; /* Non-Conformance
Location */
}
return g (); /* Non-Conformance Location */
}

Name rule85
Text Functions called with no parameters should have empty parentheses
Severity Advisory
Description
If a function call with no parameters, is specified without empty
parentheses then it can result in unexpected results.

For Example:

For a function f that returns a logical value, if the programmer


accidentally writes:
if ( f )
{
/* .... */
}
instead of
if ( f() )
{
/* .... */
}
then the statement will not do as intended. f will return a
pointer to the function, which will be non-zero and so the test
will always be true.

Name rule86
Text If a function returns error information, then that error information should be tested
Severity Advisory
Description
Interpretation: All integer-valued functions defined by the
programmer (and under analysis by Assent) are assumed to return error
codes. If the values returned by calls to such functions are either
casted to some other type or if they are ignored, then the rule is
deemed to be violated.

For Example:

int f (void);

void V1 (void)
{
int i;
float j;
f(); /* Non-Conformance
Location */
(int)f();
(float)f (); /* Non-Conformance Location */
i = f ();
i=(int)f();
j = (float)f(); /* Non-Conformance Location */
}

Name rule87
Text #include statements in a file shall only be preceded by other preprocessor directives or
comments
Severity Required
Description
All the #include statements in a particular code file should be
grouped together near the head of the file. It is important to prevent
the situation of executable code coming before a #include directive,
Otherwise there is a danger that the code may try to use items which
would be defined in the header. The rule states that a #include in a
file may be preceded only by other pre-processor directives or
comments.

Example:

#define All 0
#include <MALLOC.H designtimesp = 19250 /* malloc.h
should not be used */

void f(void)
{
}

#include <STDIO.H designtimesp = 19251 /* Non-Conformance


because - Should be at
the head of the file*/

Name rule88
Text Non-standard characters shall not occur in header file names in #include directives
Severity Required
Description
If the ',,', or /* characters are used between < and > delimiters or
the ',,or/* characters are used between the ' delimiters in a header
name pre-processing token,then the behaviour is undefined.

Example:

#include 'stde.h' /* Non-Conformance because - Non-standard


characters are not allowed */

#include 'st'd.h' /* Non-Conformance because - Non-standard


characters are not allowed */
Name rule89
Text The #include directive shall be followed by either a or filename sequence
Severity Required
Description
The directive shall take one of the following two forms:
#include 'filename'
#include

Example:

#define ABC 'abc.h'


#include ABC /* Non-Conforming because - Not in standard form*/

Name rule90
Text C Macros shall only be used for symbolic constants, function-like macros, type qualifiers
and storage class specifiers
Severity Required
Description
There are the only permitted uses of macros. Storage class specifiers
and type qualifiers include keywords such as extern,static and const.
Any other use of #define could lead to unexpected behaviour when
substitution is made, or to very hard-to-read code.Macros should
neither be used to define statements or parts of statements,nor to
redefine the syntax of the language.

Example:
/* Conforming because - Storage class specifiers is defined */
#define stor extern

/* Conforming because - type qualifiers is defined */


#define con const

/* Non-Conforming because - use typedef instead */


#define SI_32 long

/* Non-Conforming because - it is not symbolic constants,


function like macro, type qualifier, or storage class
specifiers */
#define STARTIF if(

Name rule91
Text Macros shall not be #define'd or #undef'd within a block
Severity Required
Description
While it is legal C to place #define and #undef directives anywhere
in a code file,placing them inside blocks is misleading as it implies
a scope restricted to that block,which is not the case.
Normally,#define directives should be at the start of a file,before
the first function definition.

Example:

#define ABC 2.0


void f(void)
{
/* Non-Conforming because - #define used within a block */
#define A 2
{
/* Non-Conforming because - #undef used within a
block */
#undef A
}
}

Name rule92
Text #undef should not be used
Severity Advisory
Description
The use of #undef can lead to confusion with respect to the existence
or meaning of a macro when it is used in the code.
#undef should not be normally needed.

Example:

#define A 2

/* Non-Conforming because - undef should not be used */


#undef A

Name rule93
Text A function should be used in preference to a function like macro
Severity Advisory
Description
While function-like macros can provide a speed advantage over
functions, functions provide a most robust mechanism. This is
particularly true with respect to the type checking of parameters and
the problem of function-like macros potentially evaluating parameters
multiple times.

Example:

/* Non-Conforming because - Function should be used instead of


macro*/
#define x(z) (z)

/* Non-Conforming because - Function should be used instead of


macro*/
#define d(a,b) ((a)/(b))
Name rule94
Text A function-like macro shall not be called without all of its arguments
Severity Required
Description
Example:

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

void f(void)
{
INT i = 2;

/*Non-Conforming because - Argument missing in function


like macro 'add' */
i = add(i);
}

Name rule95
Text Arguments to a function like macro shall not contain tokens that look like preprocessing
directives
Severity Required
Description
If one or more arguments to the function-like macro are not supplied
when it is called, then the behaviour is undefined.Similarly,if any
of the arguments look like pre-processor directives, the behaviour
can be unpredictable when macro substitution is made.

Example:

typedef int INT32;


typedef char CHAR;
#define join(x,y) #x##y
INT32 main (void)
{
CHAR str1[10]='Hope';

/* Invalid case - Argument to function like macro join has a


pre-processor directive*/

strcpy(str1 ,join( # include < stdio.h> , 'string'));


return 0;
}

Name rule96
Text In the definition of a function-like macro the whole definition, and each instance of a
paramter, shall be enclosed in parentheses
Severity Required
Description
Within a definition of a function-like macro,the arguments shall
always be enclosed in paranthesis and the whole expression shall
always be enclosed in paranthesis.
For example:

To define an function abs() :

#define abs(x) (((x) >= 0) ? (x):-x))

and not:

#define abs(x) x>=0 ? x : -x

If the rule is not adhered to, then when the pre-processor subsitutes
the macro into the code the operator precedence may not give the
desired results.
Consider z = abs(a-b);
If paranthesis is not used then it would be evaluated as:
z = a -b >= 0 ? a-b : -a-b;
which is wrong. By using paranthesis it can be avoided.

Few more examples:


/* Non-Conforming because - 'x' not enclosed in ()*/
#define abs1(x) ((x<0)?(x):(-(x)))

/* Non-Conforming because - 'x' not enclosed in ()*/


#define abs2(x) (((x)<0)?(x):(-x))

/* Non-Conforming because - macro definition not enclosed in ()*/


#define abs4(x) ((x)<0)?(x):(-(x))

Name rule97
Text Identifiers in preprocessor directives should be defined before use
Severity Advisory
Description
If an attempt is made to use an identifier in a pre-processor
directive,and that identifier has not been defined,the pre-processor
will sometimes not give any warning but will assume a value(usually
zero).

This is particularly true in tests such as #if.

Example:

#define x 1 /* Conforming because - x is defined */


#if x > 0
#endif

/* Other Module */

/* Non-Conforming because - x is not defined before use*/


#if x == 0
#define x 0
#endif

Name rule98
Text There shall be at the most one occurrence of the # or ## preprocessor operators in a
single macro definition
Severity Required
Description
There is an issue of unspecified order of evaluation associated with
the # and ## pre-processor operators.To avoid this problem only one
occurrence of one operator may be used in any single macro definition
(either # or ##).

Example:

/* Non-Conforming because - Both 1 # & 1 ## are used */


#define all(str) (#str##A)

Name rule99
Text All uses of the #pragma directive shall be documented and explained
Severity Required
Description
This rule places a requirement on the user of this document to
produce a list of any pragmas that they choose to use in an
application. The meaning of each pragma shall be documented. There
should be sufficient supporting description to demonstrate that the
behaviour of the pragma,and its implications for the application,have
been fully understood.

Any use of pragmas should be minimised,localised and encapsulated


within dedicated functions wherever possible.

All uses of #pragma are flagged as violations of this rule.

Example:

/* Non-Conforming because - pragma should be documented and


explained*/
#pragma WIN

/* Non-Conforming because - pragma should be documented and


explained*/
#pragma WIN2

Name rule100
Text The defined pre-processor operator shall only be used in one of the two standard forms
Severity Required
Description
The only two permissible forms for the defined pre-processor operator
are:
defined(identifier)
defined identifier
Any other form may produce undefined behaviour.

Example:

#define SUN_SOLARIS
#if defined ( MACHINE )
#define NEWMACHINE
#endif

#if defined SUN_SOLARIS


#define sparc
#endif
/* Non-Conforming because - defined preprocessor operator is not
one of the two forms given */
#if defined ( MACHINE && !SUN_SOLARIS) || !defined(MAC)
#define INTEL
#endif

Name rule101
Text Pointer arithmetic should not be used
Severity Advisory
Description
This rule refers to explicitly calculating pointer values. Any such
pointer value then has the potential to access unintended or invalid
memory address.
This is an area where there is a danger of serious errors occurring
in the code at runtime. Pointers may go out of bounds of arrays or
structures, or may even point to effectively arbitrary locations.

If pointer arithmetic is necessary, the appropriate and/or dynamic


checking code will be required to ensure that the resulting pointer
cannot point to unintended or invalid memory address. Where such use
is necessary the preferred method is to only increment and decrement
pointers using ++ or --, rather than performing other arithmetic
operations on the pointer.

So, this rule flags any pointer arithmetic operations except ++ and
-- as violations.

Name rule102
Text No more than 2 levels of pointer indirection should be used
Severity Advisory
Description
Using more than two levels of indirection can seriously impair the
ability to understand the behaviour of the code, and should therefore
be avoided.

Name rule103
Text Relational operators shall not be applied to pointer types except when both operands are
of the same type and point to the same array, struct or union
Severity Required
Description
Attempting to make comparisons between pointers is fraught with
difficulty, and in particular will produce undefined behaviour if the
two pointers do not point to the same object. Note that 'relational
operators' do not include '==' and '!='.

Name rule104
Text Non-constant pointers to functions shall not be used
Severity Required
Description
This includes explicit casts to or from pointers to functions.
'Non-constant' means pointers whose value is calculated at run time.
If the value of a pointer is known at compile time, either because it
is a constant or because it is copied from some constant value or
constant look-up table, then such use is permitted.

There is a danger with pointers calculated at run time that an error


will cause the pointer to point to an arbitrary location.Furthermore
pointers to functions cause problems with dependence on the order in
which function-designator and function arguments are evaluated when
calling functions.

Name rule105
Text All functions pointed to by a single pointer to function shall be identical in number and
type of parameters and return type
Severity Required
Description
Pointers to functions can easily violate type integrity, hence all
pointed-to functions should be of identical type.

Name rule106
Text Address of an object with automatic storage shall not be assigned to an object which
may persist after the object has ceased to exist
Severity Required
Description
If the address of an automatic object is assigned to another automatic
object of larger scope, or to a static object, then the object
containing the address may exist beyond the time when the original
object cease to exist (and its address become invalid).

Assignment of the address of an automatic variable in a part of the


program that is not reachable is not reported as a violation.

This rule is deemed to be violated if the address of an automatic


object:
* Is directly returned from a function or
* Is assigned to an identifier which is not automatic and this
assignment is not over-ridden by a subsequent assignment to the
same identifier.

Note : This version of ASSENT does not catch violations where the
address of an automatic object is assigned to an automatic variable
which is then assigned to a non-automatic variable.
Name rule107
Text Null pointers shall not be dereferenced
Severity Required
Description
This rule is checked for conservatively by ASSENT. Conservatively
means that it is intended that the tool may report non-conformances
if a pointer may have a null value at a de-reference point, though
this may never be the case at execution time.

Name rule108
Text In the specification of a structure or union type,all members of the structure or union
shall be fully specified
Severity Required
Description
If this rule is not followed, it leads to an incomplete type, which
should be avoided.

Example:

typedef int INT32;

struct badstruct1
{
INT32 a;
INT32 b []; /* Non-Conformance */
};

struct badstruct2 c; /* Non-Conformance */

union badunion1
{
INT32 d;
INT32 e []; /* Non-Conformance */
};

union badunion2 f; /* Non-Conformance */

rule109
Text Overlapping variable storage shall not be used
Severity Required
Description
This rule refers to the technique of using memory to store data and
then using the same memory to store some other data at some other time
during the execution of the program. This might be achieved by using
unions or some other mechanisms.
Example:

/*Non-Conforming code*/

typedef int INT32;


void d(void)
{
INT32 i;
struct uy
{
INT32 x;
};
union gf /* Non-conforming location */
{
INT32 f;
};
}

Name rule110
Text Unions shall not be used to access the sub-parts of larger data types
Severity Required
Description
Example:

/*Non-Conforming code*/

typedef int INT32;


typedef unsigned int UINT32;
union IntBF /* Non-conforming location */
{
INT32 i;
struct bits
{
UINT32 two : 2;
UINT32 seven1 : 7;
UINT32 seven2 : 7;
UINT32 eight : 8;
UINT32 four1 : 4;
UINT32 four2 : 4;
} b;
};

Name rule111
Text Bit fields shall only be defined to be of type unsigned int or signed int
Severity Required
Description
Example:

/*Non-Conforming code*/

typedef int INT32;


typedef unsigned int UINT32;
typedef signed int SINT32;

INT32 main(void)
{
INT32 i;
struct s{
INT32 h : 3;
UINT32 kl : 3;
SINT32 j : 4;
};
return 0 ;
}

Name rule112
Text Bit fields of type signed int shall be atleast 2 bits long
Severity Required
Description
Example:

/*Non-Conforming code*/

typedef unsigned int UINT32 ;


typedef signed int SINT32 ;

SINT32 main(void)
{
UINT32 i;
struct v {
UINT32 w :1;
SINT32 x : 1;
UINT32 y : 3;
};
return 0 ;
}

Name rule113
Text All the members of a structure or union shall be named and shall only be accessed via
their name
Severity Required
Description
Example:

/*Conforming code*/

typedef unsigned int UINT32;


typedef int INT32 ;

struct y
{
UINT32 b : 4;
UINT32 c;
};

/*Non-Conforming code*/

typedef unsigned int UINT32;


typedef int INT32 ;
struct x
{
UINT32 : 4;
UINT32 a;
};

INT32 main(void)
{
struct s
{
UINT32 a : 1;
UINT32 : 2;
};

return 0 ;
}

Name rule114
Text Reserved words and standard library function names shall not be redefined or undefined
Severity Required
Description
It is generally bad practice to #define or #undef Standard Library
functions or reserved words.It may give rise to undefined behaviour
if they are redefined or undefined.It should not be used as variables
names.
The interpretation of reserved words is as specified below:
* All identifiers that begin with an underscore or an uppercase
letter or another underscore,are always reserved for any use.
* All identifiers that begin with an underscore are always reserved
for use as identifiers with scope in both the ordinary and tag spaces
* All identifiers with external linkage are always reserved for use as
identifiers with external linkage
* The list of reserved identifiers with external linkage includes
'errno', 'setjmp' and 'va_end'
* defined and assert should not be redefined or undefined(MISRA C
Standard.)

Limitation : This rule will not be violated for #define and #undef
constructs

For Example:
#define strlen 0

typedef int INT32;


/* Non-Conforming because - Reserved word has been undefined */
#undef __LINE__

/* Non-Conforming because - Reserved word has been redefined */


INT32 __OK ;

/* Non-Conforming because - Standard function name clock has been


redefined */
enum clock {Indian,American};
Name rule115
Text Standard library function names shall not be reused
Severity Required
Description
To avoid confusion between user-defined functions and standard library
function that have same names,standard library functions names should
not be reused.

Example:

typedef int INT32;

/* Conforming because - Modified version of sqrt with new name is


written */

INT32 Mysqrt(INT32 j)
{
if(j<0)
/* check for negative value */
else
return(sqrt(j))
}

/* Non-Conforming because - Standard function name is reused */

INT32 sqrt(INT32 j)
{
if(j < 0)
/* check for negative value */
else
return(sqrt(j));
}

Name rule118
Text Dynamic heap memory allocation shall not be used
Severity Required
Description
This rule avoids the use of the functions such as 'calloc' , 'malloc'
,'realloc' and 'free'. There is unspecified,undefined and
implementation-defined behaviour associated with dynamic memory
allocation and therefore these functions should not be used.

Example:

typedef int INT32;


void *i;
void *p;

/* Non-Conforming because - calloc is used*/


p = calloc (sizeof(i),sizeof(INT32));

/* Non-Conforming because - malloc is used*/


i = malloc (sizeof(INT32));

/* Non-Conforming because - realloc is used*/


i = realloc (i, sizeof(INT32));

/* Non-Conforming because - free is used */


free(i);

Name rule119
Text The error indicator errno shall not be used
Severity Required
Description
'errno' is a facility of C, but in practice it is poorly defined
by the standard. As a result it should not be used.Even for those
functions for which the behaviour of errno is well defined, it is
preferable to check the values of inputs before calling the function
rather than rely on using errno to trap errors.

Example:

typedef int INT32;


INT32 errno;

/* Non-Conforming because - errno is used */


errno = 2;

Name rule120
Text The macro offsetof, in library<STDDEF.H designtimesp = 19104 , shall not be used
Severity Required
Description
Use of this macro can lead to undefined behaviour when the types of
the operands are incompatible or when bit fields are used.

Example:

typedef int INT32;


struct s
{
INT32 i;
} s1;

/* Non-Conforming because - macro offsetof is used */


s1.i = offsetof (struct s, i);

Name rule121
Text <LOCALE.H designtimesp = 19104and the setlocale function shall not be used
Severity Required
Description
'setlocale' function modify and query a programs locale. So the locale
shall not be changed from the standard C locale.
Example:

/* Non-Conforming because - locale.h should not be used */


#include <LOCALE.H designtimesp = 19131

/* Non-Conforming because - setlocale function should not be used*/


setlocale(2, 'qwe');

Name rule122
Text The setjmp macro and the longjmp function shall not be used
Severity Required
Description
'setjmp' and 'longjmp' are useful for dealing with errors & interrupts
encountered in a low - level subroutine of a program. These function
allow the normal function call mechanisms to be bypassed and should not
be used.

Example:

/* Non-Conforming because - setjmp.h should not be used */


#include <SETJMP.H designtimesp = 19130

jmp_buf x;

/* Non-Conforming because - setjmp macro should not be used*/


setjmp (x);

/* Non-Conforming because - longjmp macro should not be used*/


longjmp(c,i);

Name rule123
Text The signal handling facilities of<SIGNAL.H designtimesp = 19107 shall not be used
Severity Required
Description
Signal handling contains implementation-defined and undefined
behaviour and therefore it should not be used.

Example:

typedef int INT32;


typedef long int LONG;
/* Non-Conforming because - signal.h should not be used */
#include<SIGNAL.H designtimesp = 19134

INT32 i = 2;
LONG tm0 = 5L;

/* Non-Conforming because - kill should not be used */


kill(tm0,i);

/* Non-Conforming because - raise should not be used */


raise(0);

Name rule124
Text The input/output library<STDIO.H designtimesp = 19107 shall not be used in production
code
Severity Required
Description
This includes file and I/O functions 'fgetpos','fopen','ftell','gets',
'perror','remove','rename' and 'ungetc'. These functions have a large
number of unspecified, undefined and implementation-defined behaviours
associated with them.So they should not be used.

If any of the features of stdio.h need to be used in production code,


then the issues associated with the feature need to be understood.

Example:

/*Non-Conforming code*/

typedef char CHAR;


#include<STDIO.H designtimesp = 19134 /* stdio.h
should not be used*/
CHAR *s1 ;
FILE *fp;

gets (s1); /* gets should not be


used */
fp = fopen('fname','r');/* fopen should not be used */
rename('3rr','4rr'); /* rename should not be used*/
remove ('4rr'); /* remove should not
be used*/
pos = ftell(fp); /* ftell should not be used*/
x = fgetpos(fp,arr); /* fgetpos should not be used*/
y = ungetc(3,fp); /* ungetc should not be used*/
perror('This is a error message' );
/*
perror should not be used*/

Name rule125
Text The library functions atof, atoi and atol from library stdlib.h shall be used
Severity Required
Description
These functions perform the String to Numeric conversions.They have
undefined behaviour associated with them when the string cannot be
converted.

Example:

/*Non-Conforming code*/

#include<STDLIB.H designtimesp = 19133


float fl;
long l;
int i;
fl = atof ('12.34'); /* atof should not be used*/
l = atol ('43.67'); /* atol should not be used*/
i = atoi ('12.34'); /* atoi should not be used*/

Name rule126
Text The library functions abort, exit, getenv and system from library stdlib.h shall not be used
Severity Required
Description
These functions will not normally be required in an embedded system,
which does not normally need to communicate with an environment.If it
is necessary to use then it is essential to check on the implementation
behaviour of the function in the environment.

Example:

/*Non-Conforming code*/

#include <STDLIB.H designtimesp = 19133

getenv ('DARPANROOT'); /* getenv should not be used*/


system('echo hello'); /* system should not be used */
abort(); /* abort should not be
used */
exit(0); /* exit should not be
used*/

Name rule127
Text The time handling functions of library<TIME.H designtimesp = 19110 shall not be used
Severity Required
Description
These include 'time' and 'strftime'. Various aspects of these functions
are implementation dependent or unspecified,such as the formats of times,
therefore they should not be used.

Example:

/*Non-Conforming code*/

typedef long int LONG;


typedef char CHAR;
#include <TIME.H designtimesp = 19137 /* time.h is
used */

CHAR *s = 'abc', *f = 'def';


size_t sz = 0;
struct tm *tmp = NULL;
LONG *t = NULL;
time (t); /* time is used*/
strftime (s,sz,f,tmp); /* strftime is used*/
Note: rule2, rule4, rule6, rule15, rule41, rule116, rule117 are not listed above.

You might also like