0% found this document useful (0 votes)
66 views

ASML C Coding Standard

Uploaded by

s810531111
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
66 views

ASML C Coding Standard

Uploaded by

s810531111
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 103

2024/11/27 下午4:24 ASML C Coding Standard

ASML C Coding Standard


Version: 18.20

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 1/103
2024/11/27 下午4:24 ASML C Coding Standard

This document defines a standard for the production of high quality C code, and consists of a
number of rules and procedures. High quality C code is defined as being:

portable
readable
clear
unambiguous
understandable
maintainable
simply structured

Justification is provided for each rule. This involves defining a base language and then further
restricting the use of this base language to a subset satisfying the high quality issues as
mentioned before. The restrictions are chosen such that the subset contains no features that are
open to interpretation, either by a compiler or by programmers.

Scope
This standard applies to all initiated software development projects (thus including outsourced C
code). This standard does not apply to C code developed by a 3rd party or generated by a 3rd
party tool.

This standard is not intended to satisfy any legal, auditing, or quality assurance criteria.

Policy and base standard


The policy of the standard is that all rules shall be enforced by static code analyzers and code
reviews.

The base language is defined by the ANSI C89 Standard. The coding standard does allow some
compiler extensions supported by ISO C99 standard. The section arrangement has been kept
similar to the C99 standard.

Objectives of this standard


This standard aims to help developers in creating high quality C code. It therefore enforces best
practices in C development and prohibits use of a number of features of C known to lead to
portability issues, because they are unstructured or lead to unspecified, undefined or
implementation-defined behavior. In each case a justification is presented as to why the
restriction is being applied.

Because research into better subsets of languages in general and C in particular is ongoing, this
standard shall not be fixed. From time to time this standard will be reviewed and updated to
reflect the contemporary best practices in developing C code, enabling to continue with its
policy of providing high quality C code that represents the current state of the art.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 2/103
2024/11/27 下午4:24 ASML C Coding Standard

Rules and levels


Each rule has a level (range 1 through 10) assigned to it, depending on its importance. The level
is used by the integration tooling to determine if a violation has to be solved or not. Most, but
not all, rules are checkable by the SQ tool.

Disclaimer
This C-Coding Standard is provided "AS IS", without warranty of any kind and without indemnity
of any kind, express or implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall the authors or copyright
holders be liable for any claim, damages, or other liability, whether in an action of contract, tort
or otherwise, arising from, out of or in connection with the C Coding Standard, the ue of the C
Coding Standard or other dealings with the C Coding standard. This Disclaimer shall be included
in all copies or substantial protions of the C Coding Standard.

Licensing
This coding standard may only be used, copied, merged, published or distributed by licensed
companies. Licenses will only be granted in writing and upon written acceptance by TIOBE
Software.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 3/103
2024/11/27 下午4:24 ASML C Coding Standard

Change History
18.20 2024-09-10
Paul Jansen (TIOBE): - TiCS ticket 34939: Improved examples of rule
6.10.3.b.
18.19 2024-09-09
Paul Jansen (TIOBE): - TiCS ticket 34923: Improved description of rule
6.10.3.b.
18.18 2024-07-24
Paul Jansen (TIOBE): - PD-625: Introduced rule 6.5.13.b.
18.17 2024-06-21
Paul Jansen (TIOBE): - PD-868: Improved the synopsis of rule 6.8.3.b.
18.16 2024-03-15
Paul Jansen (TIOBE): - TiCS ticket 33895: Improved justification for rule
5.1.1.c.
18.15 2023-10-23
Paul Jansen (TIOBE): - PD-445: Changed synopsis of rule 6.10.3.b.
18.14 2023-09-19
Paul Jansen (TIOBE): - PD-321: Removed rule 6.8.6.3.a.
18.13 2023-07-22
Paul Jansen (TIOBE): - PD-647: Introduced rule 6.7.9.a.
18.12 2023-02-06
Paul Jansen (TIOBE): - TiCS ticket 31729: Introduced rules 5.1.1.2.h, 6.3.2.2.f,
6.4.1.1.c and 6.4.4.3.b.
18.11 2023-01-30
Paul Jansen (TIOBE): - PD-562: Changed the severity level of rule 6.8.5.1.c
and improved its description.
18.10 2023-01-07
Paul Jansen (TIOBE): - PD-420: Improved synopsis and description of rule
6.4.1.b.
18.9 2022-07-20
Paul Jansen (TIOBE):
- TiCS ticket 30754: Removed rule 6.3.2.3.a.
18.8 2022-07-05
Paul Jansen (TIOBE):
- PD-603: Improved examples of rule 5.1.2.3.b.
18.7 2022-06-23
Paul Jansen (TIOBE):
- PD-602: Improved the synopsis of rule 5.1.2.3.b.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 4/103
2024/11/27 下午4:24 ASML C Coding Standard

18.6 2022-05-07
Paul Jansen (TIOBE):
- PD-536: Added rule 6.7.5.3.c.
18.5 2022-04-28
Paul Jansen (TIOBE):
- PD-578: Added rule 6.10.1.e.
18.4 2022-04-28
Paul Jansen (TIOBE):
- PD-591: Improved the description of rule 5.1.1.b.
18.3 2022-01-31
Paul Jansen (TIOBE):
- TiCS ticket 29717: Improved description of rule 5.1.1.b.
18.2 2022-01-18
Paul Jansen (TIOBE):
- TiCS ticket 29716: Removed rule 6.10.1.d.
18.1 2022-01-12
Paul Jansen (TIOBE):
- PD-376: Added rule 6.5.3.1.b.
- PD-377: Added rule 6.5.3.4.c.
18.0 2021-05-30
Paul Jansen (TIOBE):
- Published the first public version of the ASML C Coding Standard.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 5/103
2024/11/27 下午4:24 ASML C Coding Standard

Concepts
6.2.2.b
Objects and functions with external linkage shall be declared in header files and
Synopsis
defined after including the header file that declares them.
Level 6
Category Concepts
Status Checked

Justification

Allow better scope control and avoid inconsistent declarations of function types.

6.2.2.c
A variable declaration with storage class static shall have a scope limited to the
Synopsis
source file.
Level 4
Category Concepts
Status Checked

Justification

When the variable is not defined in the source file but in a header file, you would get separate
instances of the variable; one for each translation unit.

6.2.3.a
Synopsis To avoid name collision, one shall not use the same name for different identifiers.
Level 2
Category Concepts
Status Checked

Justification

Re-declaration of identifiers results in confusing code, even if the identifiers belong to different
name spaces. Using the same name may confuse the reader.

Example

int value;
/* ... */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 6/103
2024/11/27 下午4:24 ASML C Coding Standard

{
float value; /* WRONG: obscures earlier 'value' */
/* ... */
}
/* ... */

Note

The gcc compiler option "-Wshadow" is able to check this rule. This also accounts for an
identifier declared as typedef.

6.2.4.b
Memory operations shall be symmetric; allocation and de-allocation shall take
Synopsis
place in the same scope where the allocated variable is defined.
Level 4
Category Concepts
Status Checked

Justification

Applying symmetric allocation and de-allocation decreases the risk for memory leaks
significantly.

Example

int function()
{
int result = OK;

object_struct *struct1 = NULL; /* Locally defined variable */


result = full_create(..., &struct1);

/* Use struct1 here */

result = full_destroy(..., &struct1);

return result;
}

Exception

Functions are allowed to return allocated memory through an 'out' parameter and leave the de-
allocation to the caller. It must be clearly indicated in the interface documentation when de-
allocation by the caller is required.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 7/103
2024/11/27 下午4:24 ASML C Coding Standard

6.2.5.a
Synopsis One must not rely on the actual numerical value of an enum variable.
Level 6
Category Concepts
Status Checked

Justification

The representation of enum types should not be relied upon, because this representation can
change when adding or removing items in the enum. One can iterate through an enum, but
calculations with enum values are not allowed. The language doesn't make that difference, so it
is left to the programmer to inspect the messages as relevant. Two kinds of enumerations can be
used in loops:

Enumerations with a start and finish that are not part of the enumeration itself, e.g. {
COLOR_START, RED, YELLOW, BLUE, COLOR_END }
Enumerations with a start and finish that are part of the enumeration itself, e.g. { RED,
YELLOW, BLUE }

Example 1

typedef enum number_enum_tag


{
ONE = 1,
TWO,
THREE,
FOUR
} number_enum;

number_enum n;
int fac = 1;

for (n = ONE; n <= FOUR; n++) /* RIGHT */


{
fac *= n; /* WRONG */
}

Example 2

typedef enum color_enum_tag


{
COLOR_START = 0,
RED,
YELLOW,

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 8/103
2024/11/27 下午4:24 ASML C Coding Standard

BLUE,
COLOR_END
} color_enum;

typedef enum color1_enum_tag


{
RED1 = 0,
YELLOW1,
BLUE1
} color1_enum;

color_enum enumvar;
color1_enum enumvar1;

for (enumvar = COLOR_START; enumvar < COLOR_END; enumvar++) /* RIGHT */


{
}

for (enumvar1 = RED1; enumvar1 <= BLUE1; enumvar1++) /* RIGHT */


{
}

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFIJ… 9/103
2024/11/27 下午4:24 ASML C Coding Standard

Conceptual Models
5.1.1.b
Each source file shall start with a file header, for which the "file name",
Synopsis
"description" and copyright notice are to be filled in.
Level 8
Category Conceptual Models
Status Checked

Justification

Enough information should be provided in the header to be able to understand the functionality
without reading the source code. A copyright notice describes the legal ownership of the file.

When editing a source file you can consider to update the copyright header:

For large changes, consider adding current year to the copyright year (see below)
Ensure the company name is correct

The year you state should be the year that the work is created. If a change is substantial enough
to give right to a new copyright, then that year should be mentioned too. The most important
year is the first year.

When a SW developer encounters copyright statements in existing source files that are old or
wrong, then they should:

Leave as-is until the file is touched


Updated to the latest template
Keep the original copyright years, so you could end up with 1995-2003, 2021

Example

/*------------------------------------------------------------------------------
|
| C Module
|
|-------------------------------------------------------------------------------
|
| Filename : CC_module.c
| Description:

5.1.1.c
Synopsis With respect to includes, each source file (.c and .h) shall be self-contained.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 10/103
2024/11/27 下午4:24 ASML C Coding Standard

Level 3
Category Conceptual Models
Status Unchecked

5.1.1.d
Synopsis Only files that are really needed shall be included.
Level 8
Category Conceptual Models
Status Unchecked

Justification

Inclusion of files that are not needed clutters the source text, introduces relations that are not
needed and enlarges the compilation process time.

5.1.1.f
With respect to user files, it is good practice to place the include of the header file
Synopsis
with the own definitions of the source file at the top.
Level 8
Category Conceptual Models
Status Checked

Justification

With respect to user files, it is good practice to place the include of the header file with the own
definitions of the source file at the top.

Example 1

#include <stdio.h> /* WRONG for CCBB_foo.c */


#include "CCBB_foo.h"

Example 2

#include "CCBB_foo.h" /* RIGHT for CCBB_foo.c */


#include <stdio.h>

5.1.1.1.b
The content (body) of every header file shall be enclosed in #ifndef/#if !defined,
Synopsis
#define and #endif.
Level 2

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 11/103
2024/11/27 下午4:24 ASML C Coding Standard

Category Conceptual Models


Status Checked

Justification

Since a header file may be used by source files and other header files, there is no way of
knowing in which sequence header files will be included, nor how many times any particular
header will be included. This mechanism resolves this sequencing and exclusive inclusion
problem.

Example

#ifndef CCBB_FOO_H
#define CCBB_FOO_H

<body of header file CCBB_foo.h, which is the header file of CCBB_foo.c>

#endif /* CCBB_FOO_H */

5.1.1.1.c
Naming convention of the include guard of an include file named CCBB_foo.h is
Synopsis
of format: CCBB_FOO_H
Level 6
Category Conceptual Models
Status Checked

Justification

Making the include guards unique, prevents using the same include guard for two different files.

Example

#ifndef CCBB_FOO_H
#define CCBB_FOO_H

<body of the header file, named CCBB_foo.h>

#endif /* CCBB_FOO_H */

5.1.1.2.b
Each non-trivial function shall be accompanied by a doxygen style function
Synopsis
header.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 12/103
2024/11/27 下午4:24 ASML C Coding Standard

Level 6
Category Conceptual Models
Status Checked

Justification

Enough information should be provided by the function header to help the reader to use the
function without the necessity of reading the implementation of the function and to help the
reviewer to verify whether the function has correctly been coded.

Example

/*----------------------------------------------------------------------------*/
int get_maintenance_status(
FIRST_MAINTENANCE_STRUCT *first_maintenance,
MAINTENACE_STATUST_STRUCT *maintenance_status,
const SHARED_DATE_STRUCT *sh_data)
/**
* \brief Returns the time to the next maintenance action
* \param[in] sh_data The shared data structure
* \param[out] first_maintenance Indication when first maintenance is required
* \param[out] maintenance_status Indication time to go before maintenance
* \return error status OK, SYS_ERR
* \retval

5.1.1.2.h
Synopsis Complete unfinished work
Level 8
Category Conceptual Models
Status Checked

5.1.2.b
Synopsis Local variables shall not cause stack overflow.
Level 3
Category Conceptual Models
Status Unchecked

Justification

Stack overflow can result in a critical system failure, like board reboot. Stack overflow will
happen when the total size of function arguments and local variables exceeds the available stack
size.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 13/103
2024/11/27 下午4:24 ASML C Coding Standard

This rule is only relevant for boards with limited stack size. This rule will fire when the configured
size (in the static code checker) is exceeded. In exceptional cases exceeding this limit is
acceptable and suppression of the rule by the developer is allowed. This is only allowed if the
developer is 100% sure that no runtime problem will happen.

5.1.2.3.a
Synopsis Side effects shall not be relied upon between successive sequence points.
Level 3
Category Conceptual Models
Status Checked

Justification

For a few constructs in C, the standard does not define the evaluation order when there is more
than one side-effect in it. Reliance on them can create problems which are very difficult to track
down. Note that this even may occur with the same compiler but a different set of compiler
options.

Example 1

x = i++ + a[i]; /* WRONG */


y = f() + g() /* WRONG */

Example 2

x = i + a[i]; /* RIGHT */
i++;

Example 3

y = f(); /* RIGHT */
y += g();

Note

It is best practice not to have two function calls in one statement, but usage of functions with no
(or neglectable) side effects can be used.

double d = sin(x) + fabs(x); /* RIGHT */

5.1.2.3.b
Synopsis If in doubt about operator precedence, parenthesize.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 14/103
2024/11/27 下午4:24 ASML C Coding Standard

Level 8
Category Conceptual Models
Status Checked

Justification

Mixing relational and logical operators without explicitly adding parenthesis is a notorious
source of error in C programs. However, care must be taken changing existing code which is not
properly parenthesized.

The precedence of operators in C is not intuitive. Extra parentheses aid the reader to establish
the grouping of operands.

Example 1

if (a == b && c == d && d != 0) /* WRONG */


{
/* any statement */
}

Example 2

if ((a == b) && (c == d) && (d != 0)) /* RIGHT */


{
/* any statement */
}

Example 3

if (i != 10) /* RIGHT: comparison of 1 value */


...

Example 4

if (i - k == 10 && j - k == 10) /* WRONG: precedence not clear */


...

Example 5

if (((i - k) == 10) && ((j - k) == 10)) /* RIGHT */


...

Example 6

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 15/103
2024/11/27 下午4:24 ASML C Coding Standard

if (i <= 10) /* RIGHT: comparison of 1 value */


...

Example 7

if (i - k > 10 && j - k < 10) /* WRONG: precedence not clear */


...

Example 8

if (((i - k) > 10) && ((j - k) < 10)) /* RIGHT */


...

Note

Relational operators ("<=", "<", ">" and ">=") have a higher priority than the equality operators
("==" and "!="). Be careful with changing existing code which is not properly parenthesized!

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 16/103
2024/11/27 下午4:24 ASML C Coding Standard

Conversions
6.3.a
Unsafe implicit conversions in expressions, return statements, assignment
Synopsis statements or argument lists shall not be used. Unsafe means: conversions where
values are truncated and/or sign can be lost.
Level 4
Category Conversions
Status Checked

Justification

Implicit conversions are implementation defined, therefore unsafe conversions can have
unexpected results.

Example

int i;
unsigned int ui;
long l;
float f;
double d;

l = i; /* RIGHT */
i = l; /* WRONG: value may be truncated */
d = f; /* RIGHT */
ui = i; /* WRONG: sign is lost */
i = f; /* WRONG: possible loss of data */

int f(void)
{
long l;
...
return l; /* WRONG: value may be truncated */
}

unsigned int g(void)


{
int i;
...
return i; /* WRONG: sign is lost */
}

void a(double array[100])

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 17/103
2024/11/27 下午4:24 ASML C Coding Standard

{
for (int i = 0; i < 100; i++)
{
array[i] = 0;
}
}

void b()
{
double myArray[80];
a(myArray); /* WRONG: elements 81-99 will be written to */
}

Note

Do not explicitly cast safe implicit conversions.

6.3.b
Synopsis Unsafe implicit conversions of literals shall be avoided.
Level 8
Category Conversions
Status Checked

Justification

Implicit conversions may be complex or unclearly defined. Unsafe implicit conversions should be
avoided because values can be truncated or sign can be lost. When unsafe conversions are
needed they shall be specified explicitly.

Example

void foo(int si)


{
if (si < 0x8000U) /* int converted to unsigned for comparison */
...
}

6.3.1.a
Synopsis Mixed signed/unsigned type arithmetic shall not be used.
Level 2
Category Conversions
Status Checked

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 18/103
2024/11/27 下午4:24 ASML C Coding Standard

Justification

In several cases with mixed signed/unsigned integral operands of binary operators, the signed
operand will be converted to an unsigned value. This can lead to unexpected changes of its
value, resulting in unexpected results of the expression.

Example

bool b;
int i;
char c;
short s;
unsigned int ui;
double d;
float f;

b = (i <= ui); /* WRONG: mixing signed with unsigned types gives


* unexpected results.
* If i = -10 and ui = 0 then i <= ui evaluates
* to FALSE. */

c = c + i; /* WRONG: Possibly mixing signed and unsigned since


* the definition of char being signed/unsigned
* is implementation defined. */

d = d * ui; /* RIGHT: mixing signed double with unsigned is an


* exception to this rule since it is
* perfectly safe. */
i = s % i; /* RIGHT */
d = f / d; /* RIGHT: mixing floats with doubles is allowed. */

6.3.2.1.a
Synopsis void expressions shall not be used in expressions.
Level 8
Category Conversions
Status Checked

Justification

A void expression is evaluated for its side effects. "void" expressions have no value and may not
be used in expressions.

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 19/103
2024/11/27 下午4:24 ASML C Coding Standard

void increment_counter(void);

i = increment_counter(); /* WRONG */

Note

Most compilers will check this in case a prototype is available.

6.3.2.2.a
Pointer to and from integer conversions shall not be used. For instance on 64-bit
Synopsis x86 processors the size of an integer is 32-bits while the pointer is 64-bits.
Therefore converting a pointer to an integer will discard part of the address.
Level 4
Category Conversions
Status Checked

Justification

Since such conversions involve implementation defined and undefined behavior, it is safer to
avoid their use.

Example 1

int i;
int *ip;

i = (int)ip; /* WRONG */
ip = (int *)i; /* WRONG */

Example 2

static void ccbb_f(void *p_base)


{
unsigned int offset = 0x10;
char *p_address = (char*)((unsigned int)p_base + offset); /* WRONG */
}

static void ccbb_f(void *p_base)


{
unsigned int offset = 0x10;
char *p_address = (char*)p_base + offset; /* RIGHT */
}

6.3.2.2.b
https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 20/103
2024/11/27 下午4:24 ASML C Coding Standard

Synopsis For generic pointers void * shall be used rather than char *.
Level 6
Category Conversions
Status Checked

Justification

Usage of char * as generic pointer is obsolete since 1989.

6.3.2.2.c
Synopsis Pointers shall not be converted to other pointer types.
Level 6
Category Conversions
Status Checked

Justification

Data structures have an alignment. Some structures must start on a 4 byte boundary, while for
other structures the boundary is 2 or 1. When a misaligned structure is accessed this can cause
an exception, but this differs per processor. In general casting a pointer to a pointer type with
stricter alignment requirements is dangerous.

Exception

The most common reason to cast between pointers is to convert between a generic pointer
(pointing to a memory region) and a specific pointer (pointing to a piece of data stored in this
memory region). Therefore conversion between a "void" pointer and a pointer of any other type
is allowed and does not require a cast.

To avoid having to cast through a "void" pointer before or after pointer arithmetic it is also
allowed to cast between a "char" pointer and any other pointer.

Example 1

Consider the following where a receiving pointer represents a type which has potentially stricter
memory alignment criteria than that of the type being cast:

short *s; /* 2 byte alignment */


int *i; /* 4 byte alignment */
...
i = (int *)s; /* WRONG: potential misalignment */

Example 2

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 21/103
2024/11/27 下午4:24 ASML C Coding Standard

void *p_sharedmem;
CCBB_struct *p_mystruct;
p_mystruct = p_sharedmem; /* RIGHT: exception for generic pointers */
p_mystruct->intmember = 1;
p_mystruct = (CCBB_struct *)((char *)p_sharedmem + sizeof(CCBB_struct)) /* RIGHT */

Note

If short and int are aligned as stated in the first example above then "s" may have an address
that does not represent a legal int address. It would well be possible that an address exception
would be generated on access of "i".

6.3.2.2.d
Synopsis Pointers shall not be added, multiplied nor divided.
Level 1
Category Conversions
Status Checked

Justification

A pointer is not an arithmetic type and therefore shall not be misused for arithmetic purposes.

Example

char *p;
char *q;

p += q; /* WRONG */
p *=4; /* WRONG */
p++; /* RIGHT */
p += 4; /* RIGHT */

Note

Exception: pointer + int

6.3.2.2.e
Pointers shall not be subtracted from each other, unless their unqualified type is
Synopsis
the same.
Level 2
Category Conversions
Status Checked

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 22/103
2024/11/27 下午4:24 ASML C Coding Standard

Justification

Pointer subtraction only has meaning for determining an offset.

Note

The unqualified type of a pointer is its type without "const", "volatile", etc.

Example

char *p;
char *q;
float *f;

static const char message[] = "This is a message for ...";


float g = 0.0;

p = &message[5];
q = &message[10];
f = &g;

printf("Number of elements: %d\n", q - p); /* RIGHT */


printf("Number of elements: %d\n", q - f); /* WRONG */

6.3.2.2.f
Synopsis Avoid passing type* to a void** parameter
Level 2
Category Conversions
Status Checked

6.3.2.3.d
Synopsis Avoid conversions between booleans and non-boolean types
Level 6
Category Conversions
Status Checked

Justification

Booleans are only defined in logical context. Using them in arithmetic context or converting
them to or from arithmetic types relies on the implementation of booleans, which may change
in the future.

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 23/103
2024/11/27 下午4:24 ASML C Coding Standard

bool enabled = true;


int enabled_bit;

enabled_bit = enabled; /* WRONG: assigning a bool to an int */


enabled_bit = enabled ? 1 : 0; /* RIGHT */

enabled = enabled_bit; /* WRONG: assigning int to bool */


enabled = (enabled_bit == 1); /* RIGHT */

if (enabled == 0) /* WRONG: using boolean as arithmetic type */


if (!enabled) /* RIGHT */

if (enabled_bit && enabled) /* WRONG: using arithmetic type as boolean */


if ((enabled_bit != 0) && enabled) /* RIGHT */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 24/103
2024/11/27 下午4:24 ASML C Coding Standard

Declarations
6.7.a
Synopsis Only one identifier type shall be declared on each source line.
Level 8
Category Declarations
Status Checked

Justification

Using one declaration on a line the code will become more readable and in the case of pointer
declarations not result in unexpected behavior. Besides, to be able to determine the amount of
software, a uniform way of declaring variables is required.

Example

int* i, j; /* WRONG: i is a pointer, j isn't */

long l; char c; /* WRONG */

int* m; /* RIGHT */
int n; /* RIGHT */
int i, j; /* RIGHT */

6.7.1.a
Identifiers with file scope shall be declared static, thus preventing them from
Synopsis
having global scope.
Level 4
Category Declarations
Status Checked

Justification

Giving identifiers wider scope than is necessary can easily lead to problems and reduces re-
usability.

Example

bool dbl_equal(double a, double b); /* global scope */

static int ccbb_compare(int i1, int i2); /* file scope */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 25/103
2024/11/27 下午4:24 ASML C Coding Standard

int ccbb_public; /* external scope */

static int ccbb_private; /* file scope */

6.7.1.b
Synopsis Since auto is redundant it shall be omitted to avoid cluttering up declarations.
Level 5
Category Declarations
Status Checked

Justification

"auto" clutters up declarations if it is not required and it does not add information to the code.

6.7.1.c
Since "register" is redundant it shall be omitted to avoid cluttering up
Synopsis
declarations.
Level 4
Category Declarations
Status Checked

Justification

"register" is a hint to the compiler. Most modern compilers can do a better job of register
allocation than a programmer can - it is recommended that "register" be avoided unless it can
be demonstrated that it causes a substantial improvement in speed. "register" clutters up
declarations if it is not required and it does not add information to the code.

6.7.2.a
Synopsis Compiler-specific extensions shall not be used in type specifiers.
Level 2
Category Declarations
Status Checked

Justification

Non-standard type (as defined by the ANSI standard) specifiers include so-called extensions and
are inherently not portable.

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 26/103
2024/11/27 下午4:24 ASML C Coding Standard

long long doublelong; /* WRONG */

Note

"long long" is a portable C99 type.

6.7.2.b
Synopsis Every identifier declaration shall include a type specifier.
Level 6
Category Declarations
Status Checked

Justification

Omitting the type specifier results in an implicit "int" type specifier for the declaration. Strict
definition of interfaces protects the user against inconsistently defined interfaces and is good
programming practice.

Example 1

extern CCBB_i; /* WRONG: implicit int type */

extern int CCBB_i; /* RIGHT */

Example 2

unsigned CCBB_i; /* WRONG: implicit int type */

unsigned int CCBB_i; /* RIGHT */

Example 3

CCBB_f(long a) /* WRONG: implicit int return type */


{
}

int CCBB_f(long a) /* RIGHT */


{
}

6.7.2.1.a
Do not use bit-fields for combining multiple logical values in one memory
Synopsis
location.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 27/103
2024/11/27 下午4:24 ASML C Coding Standard

Level 4
Category Declarations
Status Checked

Justification

There is no need to use bit-fields for saving memory. Furthermore, bit fields are implementation
specific (decided by the compiler) and thus not portable. Use bool instead.

6.7.2.2.a
Synopsis Mixing of different enum types is not allowed.
Level 4
Category Declarations
Status Checked

Justification

This is considered bad practice and can also result in unexpected behavior.

Example

enum Animal { CAT, DOG, PIG, HORSE };


enum Color { BLACK, RED, YELLOW };

Animal eAnimal = RED; /* WRONG */

Note

The C++ language already contains enumerated types as distinct types. Consequently, trying to
assign enumerators from one enum type to another enum type will cause a C++ compiler error.

6.7.3.a
Synopsis "const" shall be used to specify that a variable is non-modifiable.
Level 5
Category Declarations
Status Unchecked

Justification

It is a good programming practice to specify at declaration and definition of variables or


parameters that their values will not be changed or, in case of a pointer, that their reference will
not be changed.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 28/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

int get_status(DATE_STRUCT *sh_data) /* WRONG, sh_data is an input param */


/**
* \brief Returns the time to the next maintenance action
* \param[in] sh_data The shared data structure

*/
{
return sh_data->val;
}

int get_status(const DATE_STRUCT *sh_data) /* RIGHT */


/**
* \brief Returns the time to the next maintenance action
* \param[in] sh_data The shared data structure

*/
{
return sh_data->val;
}

6.7.5.a
Synopsis Only variables and parameters that are used shall be declared.
Level 4
Category Declarations
Status Checked

Justification

Variables and parameter declarations that are not used clutter the program text.

Note

In cases where you cannot remove a declaration, you can explicitly ignore the violation by
inserting this comment in front of a declaration: /*@unused@*/. Using the aforementioned
comment with a variable that is used will result in a violation.

Example

int method(
int status, /* RIGHT, parameter used */
void *context_ptr, /* WRONG, unused parameter */
/*@unused@*/ handle handle) /* RIGHT, commented unused param */
{

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 29/103
2024/11/27 下午4:24 ASML C Coding Standard

return status;
}

6.7.5.2.a
Synopsis Array bounds shall be specified as integral constant expressions.
Level 5
Category Declarations
Status Checked

Justification

Constant expressions enable tooling to check if indexing is in the defined array range. Also,
compile time undefined array size can lead to uncontrollable excessive stack usage.

Example 1

#define CCBB_ARRAY_LEN 3
#define CCBB_ARRAY_SIZE (CCBB_ARRAY_LEN + 1)

static char ccbb_array[CCBB_ARRAY_SIZE] = ""; /* RIGHT */

Example 2

static void ccbb_f(int s)


{
int a[s]; /* WRONG: array size depends on param.*/
...
}

Note

Allocate an array dynamically when using large arrays (> 1kB).

6.7.5.3.a
All function prototypes shall specify the type and the name of each of their
Synopsis
parameters.
Level 2
Category Declarations
Status Unchecked

Justification

Without declaration there is no prototype checking and that is error-prone.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 30/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

static int ccbb_f(); /* WRONG: old style declaration */


static int ccbb_f(float); /* WRONG: incomplete declaration */

static int ccbb_f(float angle); /* RIGHT: type & name of parameter mentioned */

static int ccbb_f(angle) /* WRONG: old style definition */


float angle;
{
}

static int ccbb_f(float angle) /* RIGHT: ANSI style definition */


{
}

6.7.5.3.b
Synopsis A function shall only be used if its prototype is known.
Level 2
Category Declarations
Status Checked

Justification

When a function is being used without a prototype an implicit declaration is inserted. This can
cause problems (not always detectable by the compiler) because C has no safe linkage.

6.7.5.3.c
Synopsis Avoid unused static functions
Level 8
Category Declarations
Status Checked
Static functions have file scope. If they are not called somewherein the same file as they are
defined, then they are dead and can be removed.

Example:

// file doesn't contain any call to getstatus


static int getstatus(int index) {
}

6.7.8.a

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 31/103
2024/11/27 下午4:24 ASML C Coding Standard

Synopsis All variables shall be initialized or assigned before being read.


Level 8
Category Declarations
Status Checked

Justification

Variables need not be explicitly initialized or assigned, as long as they are either initialized or
assigned ("set") before being read.

Example

{
int i;
int j;

if (...)
{
i = 1;
}
...
j = i; /* WRONG: "i" may not be initialized */
}

6.7.8.b
Synopsis The initializer for a struct, union or array shall be enclosed in braces.
Level 4
Category Declarations
Status Checked

Justification

Readability.

Example 1

typedef struct xy
{
int x;
int y;

} xyvect;

xyvect origin = 0; /* WRONG */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 32/103
2024/11/27 下午4:24 ASML C Coding Standard

xyvect point = /* RIGHT */


{
0,
0
};

origin = point; /* assignment */

Example 2

#define CCBB_STX 0x02


#define CCBB_EOT 0x04
#define CCBB_ACK 0x06

static const char ccbb_protocol[3] = /* RIGHT */


{
CCBB_STX,
CCBB_EOT,
CCBB_ACK
};

Exception

Initialization of a character array with a string literal does not require braces:

static const char ccbb_msg[] = "My message";

Note

When copying structs with pointers as members, be aware that the pointer is duplicated and not
the memory it is referring to.

6.7.8.c
Synopsis For a struct the initializer should be {0} or all fields should be initialized.
Level 4
Category Declarations
Status Checked

Justification

Readability.

Example 1

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 33/103
2024/11/27 下午4:24 ASML C Coding Standard

typedef struct xyz


{
float x;
float y;
float z;
} xyz_vect;

xyz_vect a = {0}; /* RIGHT */


xyz_vect b = {1.0, 3.5, 6.7}; /* RIGHT */
xyz_vect c = {1.0, 3.5} /* WRONG: c is interpreted as {1.0, 3.5, 0.0} */

Example 2

typedef struct rotate


{
xyz_vect hor;
float Rx;
float Ry;
float Rz;
} rotate_vect;

typedef struct foo


{
xyz_vect hor;
rotate_vect rot;
} foo_vect;

foo_vect a = {{0}, {0}}; /* RIGHT */


foo_vect b = {{1.0, 3.5, 6.7}, {0}}; /* RIGHT */
foo_vect c =
{
{1.0, 3.5}, /* WRONG: c.hor is interpreted as {1.0, 3.5, 0.0}. */
{3.1415, 1.41, 0.707} /* Unknown if this was intended by the programmer */

6.7.8.d
Synopsis All variables containing a pointer shall be initialized.
Level 6
Category Declarations
Status Checked

Justification

In this way uninitialized memory is banned out.

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 34/103
2024/11/27 下午4:24 ASML C Coding Standard

int* i; /* WRONG, pointer not initialized */


int* j = NULL; /* RIGHT */

typedef struct Foo {


int* x;
} Foo;

Foo foo1; /* WRONG, struct containing pointer not initialized */


Foo foo2 = {0}; /* RIGHT, struct initialized */

6.7.9.a
Synopsis Use the correct number of elements to initialize an array
Level 2
Category Declarations
Status Checked

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 35/103
2024/11/27 下午4:24 ASML C Coding Standard

Environmental Considerations
5.2.1.1.b
Synopsis Digraphs shall not be used: "<:", ":>", "<%", "%>", "%:".
Level 2
Category Environmental Considerations
Status Checked

Justification

Digraphs are not required and accidental use can cause problems.

Note

Those characters are confusing and obsolete, since keyboards, editors and compilers allow the
usage of (respectively): "[", "]", "{", "}", "#", "##".

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 36/103
2024/11/27 下午4:24 ASML C Coding Standard

Expressions
6.5.a
Synopsis Bitwise operations shall only be applied on operands of unsigned type.
Level 4
Category Expressions
Status Checked

Justification

Bitwise operations on operands of signed type may result in undefined behavior and
implementation defined behavior.

Example

int mask = 0x80000000;


unsigned int u = mask >> 24; /* WRONG */

Note

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has
a signed type and a non-negative value, the value of the result is the integral part of the
quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is
implementation defined.

6.5.2.1.a
Array subscripting requires a pointer to object type and one or more integral
Synopsis subscript expressions. The indices must be within the bounds values of the
(allocated) array.
Level 1
Category Expressions
Status Checked

Justification

Language constraint. To avoid memory access outside the array the index should be within the
bounds of the array.

Example

int i;
int a[6];

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 37/103
2024/11/27 下午4:24 ASML C Coding Standard

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


{
a[i] = 0; /* WRONG: Index gets a value greater than the number of elements. */
}

6.5.2.1.b
Synopsis typedef for an array of unknown size shall not be used.
Level 1
Category Expressions
Status Unchecked

Justification

Using a typedef for an array of unknown size can lead to implementation defined behavior. The
ANSI standard does not define if or when an unsized array typedef is actually given a size.

Example

typedef int array[];

/* ... */
array x = {1,2}; /* WRONG */

6.5.2.2.b
Synopsis Do not declare functions within functions.
Level 3
Category Expressions
Status Checked

Justification

For portability reasons (ANSI C89 does not allow this) do not declare a function within a
function.

Example

int CCBB_f(void)
{
int r = OK;

static int ccbb_foo(void) /* WRONG */


{

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 38/103
2024/11/27 下午4:24 ASML C Coding Standard

...
}
};

6.5.2.2.c
Synopsis Do not use functions marked as deprecated.
Level 6
Category Expressions
Status Checked

Justification

Adding new uses of deprecated functions or macros makes it harder to get rid of these legacy
functions or macros. One might also risk using a function or macro for which support will end
soon.

Example

Use waiting_for_condition instead of the deprecated wait_for_condition.

Note

The new interfaces will be added in the SQ Tool configuration based on the decision of the
component owner. This configuration is customizable per release. Please contact the owner of
the functional element for advice when this rule yields a violation in your code.

6.5.2.3.a
When structures are accessed by means of a pointer, the pointer-to notation ->
Synopsis rather than the member notation * shall be used to denote a specified member of
the structure.
Level 8
Category Expressions
Status Checked

Justification

The pointer-to notation is more clear when reading the code, since it looks less cluttered and it
becomes obvious that a member of a struct or union is meant.

Example

i = p->value; /* RIGHT */
i = (*p).value; /* WRONG */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 39/103
2024/11/27 下午4:24 ASML C Coding Standard

6.5.2.3.b
Structs or unions must be passed by reference into functions with variable
Synopsis
numbers of parameters.
Level 5
Category Expressions
Status Checked

Justification

The C standard requires that the type of function arguments matches the type of the parameters
the function expects. Arguments for functions with variable numbers of parameters cannot be
verified at compile time; therefore potential mismatches can only be detected at run time.

Passing a struct or union by value while the function expects a reference (or vice versa) is a
common type of programming error. The runtime problem may not even appear with certain
compiler- or target settings, making the programming error hardly detectable.

This rule aims to prevent this type of error by limiting the number of ways a struct or union may
be passed to functions with variable numbers of parameters.

Example

{
timestamp time;

...

trace(CC, TRACE_INT, __func__, "time=%T", time); /* WRONG */


trace(CC, TRACE_INT, __func__, "time=%T", &time); /* RIGHT */
}

6.5.2.3.d
Synopsis Do not use nested structures.
Level 6
Category Expressions
Status Checked

Justification

The scoping rules between C and C++ structures are different. The fields of a nested structure
are directly accessible in C, but not in C++. So using nested structures might thus result in
different and unexpected behavior.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 40/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

typedef struct {
int size;
struct {
int x;
int y;
} Point;
} Mystruct; /* WRONG */

typedef struct {
int x;
int y;
} Point;

typedef struct {
int size;
Point p;
} Mystruct; /* RIGHT */

6.5.3.1.a
Synopsis Do not mix postfix and prefix increment and/or decrement in a statement.
Level 3
Category Expressions
Status Checked

Justification

Expressions are particularly confusing to read when both postfix and prefix forms are used
simultaneously.

Example

x++ + --j; /* WRONG */

6.5.3.1.b
Synopsis Don't increment (decrement) a pointer to a function.
Level 2
Category Expressions
Status Checked
The increment and decrement operators are not valid for pointers to functions. See the
StackOverflow reference for more details. For instance:

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 41/103
2024/11/27 下午4:24 ASML C Coding Standard

function_ptr++; /* WRONG */

6.5.3.2.a
Synopsis A variable declared as an array shall not be used as a pointer.
Level 6
Category Expressions
Status Checked

Justification

An array name acts as a pointer to the first element of the array. However, using it that way can
be a source of programming errors if the programmer forgets to process other elements of the
array.

Example 1

{
int a[10];

*a = 1; /* WRONG */
a[0] = 1; /* RIGHT */
}

Example 2

typedef struct
{
int x;
int y;
} ccbb_struct_t;

static void ccbb_f(void)


{
ccbb_struct_t a[3];

a->x = 1; /* WRONG */
a[0].x = 1; /* RIGHT */
}

Note

An array name can be assigned to a pointer, making it a pointer to an array element. In this case,
the programmer's intention is clear.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 42/103
2024/11/27 下午4:24 ASML C Coding Standard

Example 3

{
int a[10];
int *a_p;

*a = 1; /* WRONG */

a_p = a;
*a_p = 1; /* RIGHT */
}

6.5.3.3.a
Synopsis The unary plus operator shall not be used.
Level 6
Category Expressions
Status Checked

Justification

The unary plus is never really needed in code. It could be an indication of a programming
mistake.

Example

strlen(*ddl_string) + + sizeof(","); /* WRONG: was this intended? */

6.5.3.3.b
Synopsis Unary minus shall only be applied to an operand having a signed arithmetic type.
Level 1
Category Expressions
Status Checked

Justification

Unary minus on an unsigned expression gives an unsigned result which is never negative; unary
minus on a non-arithmetic expression is not allowed.

Example

long j;
unsigned int i = 1;
signed int k = 1;

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 43/103
2024/11/27 下午4:24 ASML C Coding Standard

...
j = -i; /* WRONG: very large positive number */
j = -k; /* RIGHT */

Note

The negative is taken after any necessary promotions have been applied to the operand.

6.5.3.4.a
Synopsis sizeof shall not be applied to an expression with side-effects.
Level 3
Category Expressions
Status Checked

Justification

The operand of sizeof is only evaluated at compile time so the side-effects that would normally
occur at run time do not take place. This may seem non-intuitive to the novice.

Example

x = sizeof(i++); /* WRONG: i not changed */

6.5.3.4.b
Synopsis Don't use sizeof on a variable of an array type that is passed as argument.
Level 2
Category Expressions
Status Checked

Justification

Variables of array types are treated as pointers when passed as arguments. As a result the sizeof
operator will return the size of the array type instead of the size of the array. This is not intuitive
and can easily lead to mistakes.

Example

void m1(char a[100]) {


int x = sizeof(a); /* WRONG, x == 4 or x == 8 */
}

void m2(void) {
char a[100] = { 0 };

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 44/103
2024/11/27 下午4:24 ASML C Coding Standard

int x = sizeof(a); /* RIGHT, x == 100 */


}

6.5.3.4.c
Synopsis Don't apply sizeof to a function.
Level 2
Category Expressions
Status Checked
The sizeof operator is not defined for functions:

size_t n = sizeof(function); /* WRONG */

6.5.4.a
Synopsis Casting shall only be used to denote required casting.
Level 8
Category Expressions
Status Checked

Justification

Casting requires special attention from the reader of the source code and should not be used
when not needed. Casting is required in unsafe (loss of sign, loss of precision) implicit
conversions.

Example

const int m = 5;

long p = (long) m; /* WRONG, conversion from int to long is safe */

int* q = (int*) &m; /* RIGHT, unsafe conversion to non-const */

6.5.7.b
The right operand of a left shift operator for a signed type as left operand shall
Synopsis
not be so large that the resulting value cannot be represented.
Level 4
Category Expressions
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 45/103
2024/11/27 下午4:24 ASML C Coding Standard

Such shifts lead to undefined behavior. In general, only the constant case is statically detectable,
for example:

Example

int a = 3;
int b;

b = (a << 46); /* WRONG: int may be 32 bits */

6.5.8.a
Synopsis Comparison of unsigned operands shall not occur against negative values.
Level 6
Category Expressions
Status Checked

Justification

Such code is useless and probably a bug.

Example

/* The negative constant (NEG) will be converted to a (positive) "large"


* unsigned int. The result is a comparison of uia with a positive
* unsigned value.
*/

unsigned int uia;

if (uia < NEG) /* NEG converted to unsigned (positive) int */


{
...
}

6.5.8.c
Synopsis Don't compare floats of different types.
Level 6
Category Expressions
Status Checked

Justification

Difference in precision may result in unexpected result.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 46/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

float test1 = 10.1;


double test2 = 10.1;

if (test1 > test2) /* WRONG: TRUE, because test1 = 10.1000038 and test2 = 10.1 */
if ((double)test1 > test2) /* WRONG: TRUE, because test1 = 10.1000038 and test2 = 10.1
*/
if (test1 > (float)test2) /* RIGHT: FALSE, because test1 = test2 = 10.1000038 */

Note

Note that in the example above casting will remove the violation but only casting to the lower
precision type will make the numbers comparable (at the cost of information loss).

6.5.8.d
Comparison of floating point numbers (float or double) shall preferably be
Synopsis
avoided.
Level 8
Category Expressions
Status Unchecked

Justification

Floating point numbers are by definition inaccurate and rounding errors can be accumulated
during computation.

Example

float test1 = 10.1;


float test2 = 10.099;
float test3 = test2 + 100000;
test3 -= 100000;

if (test1 > test2) /* true */

if (test1 > test3) /* false, because test1 = 10.10000038 and test3 = 10.10156250 */

6.5.8.e
Synopsis Use memcmp only to compare arrays of scalar types.
Level 2
Category Expressions
Status Unchecked

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 47/103
2024/11/27 下午4:24 ASML C Coding Standard

Justification

Compilers add padding bits to structs and unions to have memory alignment. Padding bits are
not required to be initialized during struct, union initialization. When comparing two structs with
memcmp padding bits are checked too. memcmp result is likely return false even though two
structs are the same. Therefore, use memcmp only to compare arrays of scalar types. If you want
to compare structs, do a member wise comparison.

Example

struct SimpleStruct
{
char simple_char;
/* compiler will add 3 padding bits char[3] */
int simple_int;
};

struct SimpleStruct struct1 = {'a', 0};


struct SimpleStruct struct2 = {'a', 0};

/* WRONG, returns 1 (false) in most of the cases */


if( memcmp(&struct1, &struct2, sizeof(struct SimpleStruct) ) == 0)
{
/* do something */
}

int a[3] = {1, 2, 3};


int b[3] = {1, 2, 3};

/* RIGHT, always returns true */


if( memcmp(&a, &b, sizeof(int) * 3) )
{
/* do something */
}

6.5.8.f
Synopsis Do not compare floating point numbers with memcmp.
Level 8
Category Expressions
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 48/103
2024/11/27 下午4:24 ASML C Coding Standard

Special floating values (e.g. NaN, -0, +0) are not safe to be compared with memcmp. Their
logical equality and bit-wise equality differ.

Example

double a = NAN;
double b = NAN;

if( a == b ) /* returns false, not equal */


{
/* do something */
}

/* WRONG, returns 0 which means equal */


if( memcmp(&a, &b, sizeof(double)) == 0 )
{
/* do something */
}

double c = 0;
double d = (double) -2 * 0; /* negative zero, -0 */

if( c == d ) /* returns true, equal */


{
/* do something */
}

/* WRONG, returns 1 which means not equal */


if( memcmp(&c, &d, sizeof(double)) == 0)
{
/* do something */
}

6.5.9.a
Synopsis Pointer comparison shall only be done for compatible pointer types.
Level 2
Category Expressions
Status Checked

Justification

Language constraint.

6.5.9.b

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 49/103
2024/11/27 下午4:24 ASML C Coding Standard

Floating point expressions shall not be compared using the "==", "!=" operators.
Synopsis
Floating point expressions shall be compared using special functions.
Level 3
Category Expressions
Status Checked

Justification

Comparing floating point expressions for equality or inequality is a notorious and well-
documented source of software system failures.

Example 1

#include "floatcompare.h"

double CCBB_calculate(void);
double d;

d = CCBB_calculate();
if (d != 0.0F) /* WRONG: d might be close to 0 */
...
if (!dbl_equal(d, 0.0)) /* RIGHT */
...

Example 2

double d;

for (d = 0.0; d != 30.0; d = d + 1.0) /* WRONG, d will never become exactly 30.0 */
/* any statement */
}

Example 3

#include "floatcompare.h"

double min = 10.0;


double sns;
double eps = 0.01; /* epsilon: 10% of sensor resolution */

sns = CCBB_read_sensor();
if (dbl_equal_relative(sns, min, eps)) /* RIGHT */

Example 4

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 50/103
2024/11/27 下午4:24 ASML C Coding Standard

double d;
...
if (d == 0.0) /* WRONG */
{
/* Any statement */
}

Example 5

#define CCBB_D_EPSILON (1.0e-11) /* 1% of smallest resolution of d */

ccbb_get_d(d);

if (dbl_equal_absolute(d, end_d, CCBB_D_EPSILON)) /* RIGHT */


{
/* Any statement */
}

Note

In some code, a variable is tested on 0.0 before it is used in a division. It is certain that the
programmer had a good intention, but still the code can be criticized. If you divide by a very
small number, an overflow can occur. The same can be said about testing for NAN.

It is rather strange to say that 0.0 is a special situation, while 1 * 10-12 isn't.

A good programming practice is to test the initial values on their range. If during a calculation
there is some doubt if the new values are still within a reasonable range, a new range test can be
made. If this way of programming is well thought through, then it is not necessary to test on 0.0
before every division. Like in programming with pointers, you do not test on NULL for every
pointer dereference.

It does occur that a float is tested on 0.0 to see if something has been initialised. In general, this
is bad coding practice because the value has a second meaning in such case. First, it says if
something has been initialized and second, it contains the result of a measurement (that value
should never be 0.0!). This problem is difficult to remove in old code.

6.5.13.a
The right-hand operand of the "&&" or "||" operator shall not contain any side-
Synopsis
effects.
Level 6
Category Expressions
Status Unchecked

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 51/103
2024/11/27 下午4:24 ASML C Coding Standard

Justification

The right-hand operand of a "&&" or "||" is conditionally executed. Besides, the precedence of
operators in C is not intuitive.

Example 1

if ((a > b) && (i++ != 0)) /* WRONG: i not always changed */

Example 2

if ((a > b) && (i != 0)) /* RIGHT */


...

Example 3

if (a > b)
{
i++; /* RIGHT */
}

6.5.13.b
Synopsis Avoid complex conditions
Level 5
Category Expressions
Status Checked

6.5.15.a
The second and third operand of a conditional expression of the conditional
Synopsis
operator shall not contain side-effects.
Level 6
Category Expressions
Status Checked

Justification

Example 1

(a > b) ? i++ : j++; /* WRONG: only one of i and j are incremented */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 52/103
2024/11/27 下午4:24 ASML C Coding Standard

Example 2

if (a > b) /* RIGHT */
{
i++;
}
else
{
j++;
}

Example 3

/* Search for "\n" in string and print the string or an error message. */

{
p = strchr(string, "\n");
printf("Result: %s\n", (p != NULL) ? p : "NOT FOUND"); /* RIGHT */
}

6.5.16.a
Synopsis Do not use nested assignments.
Level 8
Category Expressions
Status Checked

Justification

Nested assignments are most of the time used unintentionally causing unexpected behavior.

Example

x = /* WRONG */
y =
z = 0;

x = 0; /* RIGHT */
y = 0;
z = 0;

6.5.16.b
Synopsis Do not discard const qualifiers in pointer assignments.
Level 6

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 53/103
2024/11/27 下午4:24 ASML C Coding Standard

Category Expressions
Status Checked

Justification

Discarding const qualifiers in pointer assignments is allowed in C but not in C++. In order to
keep code being portable to C++, it is not recommended to perform such assignments.

Example

const int* p;
int* q;
q = p; /* WRONG */

const int* p;
const int* q;
q = p; /* RIGHT */

6.5.17.a
Synopsis The comma operator shall not be used.
Level 6
Category Expressions
Status Checked

Justification

Using the comma operator is confusing and is always avoidable without any loss of readability,
program size or program performance.

Example

a = (b++, c++); /* WRONG */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 54/103
2024/11/27 下午4:24 ASML C Coding Standard

External Definitions
6.9.1.a
Function pointer parameters should not be declared as ordinary pointer type. A
Synopsis
type should be used which is declared by a "typedef" declaration.
Level 6
Category External Definitions
Status Checked

Justification

Improves readability.

Example 1

/* WRONG example of function with parameters defined as pointer type. */

void CCBB_exec_test(
int test_param_version_number,
int (*input_fun)(bool, void *, void **, int *),
int (*exec_fun)(void *),
int (*normal_fun)(void));

Example 2

/* RIGHT example of function with parameters declared as non-pointer type */

/*-------------------------------------------------------------------------|
| Module typedefinitions |
|-------------------------------------------------------------------------*/

/* Type declarations of functions to be implemented */


typedef int(*input_funcptr)(bool use_params,
void *input_p,
void **output_pp,
int *output_size_p );

typedef int (*exec_funcptr)(void *input_p);

typedef int (*normal_funcptr)(void);

/*-------------------------------------------------------------------------|
| Module Exported functions |

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 55/103
2024/11/27 下午4:24 ASML C Coding Standard

|-------------------------------------------------------------------------*/

void CCBB_exec_test(
int test_param_version_number,
input_funcptr input_func,
exec_funcptr exec_func,
normal_funcptr normal_func);

6.9.1.b
Synopsis Do not use K&R declaration style.
Level 6
Category External Definitions
Status Checked

Justification

K&R declaration style is not supported in C++. So programs will not be portable from C to C++
if they use this style of declaration.

Example

int foo(a, p) /* WRONG, K&R style */


int a;
char* p;
{
return 0;
}

int foo(int a, char* p) /* RIGHT, ANSI style */


{
return 0;
}

6.9.2.a
Synopsis Explicitly use "static" or "extern" on all global const declarations.
Level 6
Category External Definitions
Status Checked

Justification

Adding static or extern makes the scope of the const variable explicit.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 56/103
2024/11/27 下午4:24 ASML C Coding Standard

6.9.2.b
Synopsis Only static global variables that are used shall be declared.
Level 8
Category External Definitions
Status Unchecked

Justification

If a static global variable is not used at all, it better can be removed.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 57/103
2024/11/27 下午4:24 ASML C Coding Standard

Lexical Elements
6.4.b
Synopsis The tab character (0x09 ASCII) shall not be used.
Level 8
Category Lexical Elements
Status Checked

Justification

Some tooling will fail (!) if the tab character is used (for instance automatic merging could go
wrong).

Note

Also different "tab to a number of space (0x20 ASCII) character translations" in different editors
can lead to a different layout per editor. Manual merging with a garbled layout will lead to
merge errors, review errors, etc.

6.4.1.a
Synopsis C keywords are reserved for use as keywords and shall not be used otherwise.
Level 2
Category Lexical Elements
Status Checked

Justification

The use of keywords other than as keywords leads to undefined behavior.

Example

int if; /* WRONG */

Note

C keywords are:

auto break case char const continue


default do double else enum extern
float for goto if inline int
long register restrict return short signed
sizeof static struct switch typedef union

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 58/103
2024/11/27 下午4:24 ASML C Coding Standard

unsigned void volatile while _Bool _Complex


_Imaginary

6.4.1.b
Synopsis No inline assembler is allowed
Level 2
Category Lexical Elements
Status Checked

6.4.1.1.a
Synopsis Do not use C++ keywords.
Level 6
Category Lexical Elements
Status Checked

Justification

Keywords from C++ shall not be used as identifier names because of portability and
interoperability.

Example

int class; /* WRONG */

Note

C++ keywords that are not available in C are:

alignas alignof auto bool


catch char16_t char32_t class
constexpr const_cast decltype delete
dynamic_cast explicit export false
friend mutable namespace new
noexcept nullptr operator private
protected public public reinterpret_cast
static_assert static_cast template this
thread_local throw true try
typeid typename using virtual
wchar_t

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 59/103
2024/11/27 下午4:24 ASML C Coding Standard

6.4.1.1.b
Do not use C++ alternative representations that are not part of the C keywords
Synopsis
(see also 6.4.1.a).
Level 4
Category Lexical Elements
Status Checked

Justification

Alternative representations from C++ shall not be used as identifier names because of
portability and interoperability.

Example

int bitand; /* WRONG */

Note

C++ alternative representations are:

and and_eq bitand bitor


compl not not_eq or
or_eq xor xor_eq

6.4.1.1.c
Synopsis Do not declare struct, union, and enum types in function prototypes
Level 7
Category Lexical Elements
Status Checked

6.4.2.a
Synopsis Identifiers shall satisfy the standard C syntax for identifiers.
Level 2
Category Lexical Elements
Status Checked

Justification

Implementation defined extensions on the characters allowed in an identifier hamper portability


of the source code.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 60/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

int a$b; /* WRONG */

6.4.2.b
Synopsis Identifiers shall not be defined with one or more leading underscores (_).
Level 5
Category Lexical Elements
Status Checked

Justification

Leading underscores are reserved for compiler writers.

Example

int _tmpval; /* WRONG */


#define _TEMPCONST (19) /* WRONG */

6.4.2.d
Synopsis Don't use extern variable declarations in header files, except for consts.
Level 6
Category Lexical Elements
Status Checked

Justification

Functions should be used to control the access to variables and allow the implementation to use
synchronization (for multi-threaded use). This holds especially for arrays, because the function
call can provide destination-buffer size checking and protects the client from array size changes
beyond what it is capable of handling.

Example

In header files:

/* WRONG */
extern error_desc_type error_table[];
extern choice_menu menu;
/* RIGHT */
const int i = 5;

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 61/103
2024/11/27 下午4:24 ASML C Coding Standard

6.4.4.b
Synopsis Use suffix 'L' instead of 'l' to avoid confusion
Level 8
Category Lexical Elements
Status Checked

Justification

This small letter suffix shall not be used to avoid any confusion between l (letter l) and 1 (digit 1).

Example

#define FAR_AWAY (0.0l) /* WRONG */


#define CLOSE_BY (0.0L) /* RIGHT */

6.4.4.1.a
Synopsis Only decimal or hexadecimal notation may be used for integer constants.
Level 6
Category Lexical Elements
Status Checked

Justification

To avoid confusion by the reader. The octal prefix "0" compared to the hexadecimal prefix "0x" is
inconspicuous. The reader could easily interpret octal numbers as decimal numbers.

Example

011 octal = 9 decimal (and not 11 decimal).

6.4.4.1.b
Use clear constant values. Small letters shall not be used, expecially to avoid
Synopsis confusion between l (letter l) and 1 (digit one). The letter U shall be written in
uppercase to be consistent with the case of the letter L.
Level 8
Category Lexical Elements
Status Checked

Justification

Readability.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 62/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

#define CCBB_FIRST_DATE 19960101UL /* RIGHT */


#define CCBB_LAST_DATE 20960101ul /* WRONG */

6.4.4.3.a
Synopsis Only the first entry in an enumerator shall be explicitly defined using '='.
Level 8
Category Lexical Elements
Status Checked

Justification

This rule prevents gaps in the enumeration values, which make iterating over the enum
impossible.

Example

enum days
{
MONDAY = 3, /* RIGHT: only first enum is defined */
TUESDAY,
WEDNESDAY
} day;

6.4.4.3.b
All enum element names should start with the same prefix in capitals to avoid
Synopsis
name clashes
Level 6
Category Lexical Elements
Status Checked

6.4.4.4.a
Synopsis Only ANSI defined escape sequences shall be used.
Level 2
Category Lexical Elements
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 63/103
2024/11/27 下午4:24 ASML C Coding Standard

Escape sequences (those beginning with \) other than those defined by the ANSI standard have
undefined behavior, impacting both reliability and portability.

Example

char a = '\x'; /* WRONG */


char b = '\xfff'; /* WRONG */
char c = '\777'; /* WRONG */
char d[] = "\x"; /* WRONG */
char e[] = "\y"; /* WRONG */
char f = '\x; /* WRONG */
char g = '\8'; /* WRONG */
char h = '\n'; /* RIGHT */

6.4.5.a
Synopsis A character string literal token shall not be adjacent to a wide string literal token.
Level 2
Category Lexical Elements
Status Checked

Justification

String operation will give undefined results in C89.

Example

#define HELLO "Hello"


#define LHELLO L"Hello"
#define WORLD "World."
#define LWORLD L" World."

const char *text1 = HELLO LWORLD; /* WRONG */


const char *text2 = HELLO WORLD; /* RIGHT */

6.4.9.a
Synopsis Comments in the form of opening (/*) and closing (*/) shall not be nested.
Level 2
Category Lexical Elements
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 64/103
2024/11/27 下午4:24 ASML C Coding Standard

C does not support nesting of comments. However, some compilers allow this as a language
extension. If so, the following code will not give a syntax error but just compiles and treat the
critical function call as comments.

Example 1

/* some comment /* WRONG */


perform_critical_function();
/* some other comment */

Example 2

/* This code is bracketed out because ... /* RIGHT */


* code_to_be_excluded(); some other comment
*/

Note

The main argument for nesting comments is that it would allow programmers to "comment out"
code. However, comments shall be used for adding documentation to a program and preferably
mechanisms that already exist for source code exclusion shall be used.

6.4.9.c
Synopsis Do not use mixed comments.
Level 8
Category Lexical Elements
Status Checked

Justification

Some editors are not able to parse mixed comments (C and C++ style) correctly, thus displaying
the entire file as being one comment if this occurs in the header block.

Example

//*********************************************** /* WRONG */
//----------------------------------------------- /* RIGHT */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 65/103
2024/11/27 下午4:24 ASML C Coding Standard

Library
7.2.a
Synopsis The standard header file assert.h shall not be used.
Level 4
Category Library
Status Checked

Justification

Usage of <assert.h> macros can lead to uncontrolled termination of code which is prohibited.

7.12.a
The arguments to any mathematical function shall be within the appropriate
Synopsis
range.
Level 2
Category Library
Status Checked

Justification

When supplied a bad argument, the returned value cannot be used, as it is either NAN or an
implementation specific value.

Example 1

alpha = asin(a / c); /* WRONG if abs(argument) can be > 1 */


r = a / c; /* RIGHT: check argument before use */
if (abs(r) > 1)
{
/* handle error */
}
else
{
alpha = asin(r);
}

Example 2

c = sqrt(b * b - a * a); /* WRONG if argument can be negative */


d = (b * b) - (a * a); /* RIGHT: check computation result */
if (d < 0)

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 66/103
2024/11/27 下午4:24 ASML C Coding Standard

{
/* handle error */
}
else
{
c = sqrt(d);
}

Note

Math functions with "out of range" risk are "asin", "acos", "sqrt", "log", and "log10".

7.12.b
Any calculation result shall not overflow the corresponding output parameter or
Synopsis
return value data type.
Level 2
Category Library
Status Unchecked

Justification

When supplied some very large input argument, the returned value could overflow, shown as Inf
or -Inf value.

Example

y = exp (a * b); /* WARNING: a * b could be too large */


alpha = sqrt(a / c); /* WRONG if arguments can be negative */

Justification

The following mathematical functions have an "overflow" risk: "ldexp", "sinh", "cosh", "exp", and
"pow".

7.13.a
Synopsis The setjmp() function and its counterpart longjmp() shall not be used.
Level 3
Category Library
Status Checked

Justification

The use of longjmp() results in unstructured code.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 67/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

#include <setjmp.h>
jmp_buf env;
if (setjmp(env) != 0) /* WRONG */
{
longjump(env); /* WRONG */
}

7.18.a
Synopsis Do not define types or macros with the same name as types or macros in stdint.h.
Level 4
Category Library
Status Checked

Justification

With some compiler versions stdint.h will be included by default. Defining one's own variables,
types or macros with the same names as defined in stdint.h may cause conflicts.

Example

long int32_t; /* WRONG */

Note

Some examples of types defined in stdint.h are: int8_t, uint8_t, int32_t, uint32_t, int_least8_t,
int_fast8_t, intptr_t, and intmax_t. Some examples of macros defined in stdint.h are: UINT64_C,
INT16_MIN, INT64_MAX, INT_FAST32_MAX, INTPTR_MIN, and UINTMAX_MA.

7.19.a
Only standard output specifiers and standard flags shall be used in output format
Synopsis
specifications.
Level 2
Category Library
Status Checked

Justification

The use of non-standard output specifiers or non-standard flags is not portable.

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 68/103
2024/11/27 下午4:24 ASML C Coding Standard

printf("%#i", i); /* WRONG */


printf("%Lo", i); /* WRONG */
printf("%#u", i); /* WRONG */
printf("%Lx", i); /* WRONG */
printf("%LX", i); /* WRONG */
printf("%hf", f); /* WRONG */
printf("%he", f); /* WRONG */
printf("%hE", f); /* WRONG */
printf("%hg", d); /* WRONG */
printf("%hG", d); /* WRONG */
printf("%#c", c); /* WRONG */
printf("%#%"); /* WRONG */
printf("%#s", p); /* WRONG */
printf("%#n", p); /* WRONG */
printf("%#p", v); /* WRONG */
fprintf(stderr, "error occurred: %m\n”); /* WRONG */

7.19.b
The arguments in a formatted output function shall match the output specifiers in
Synopsis
the format specification.
Level 1
Category Library
Status Checked

Justification

Execution leads to undefined results when an output specifier and argument type do not match.

Example

printf("%i", p); /* WRONG */


printf("%ll", l); /* WRONG */
printf("%o"); /* WRONG */
printf(" ", i); /* WRONG */

Note

Format specifier must be constant, when possible, to allow checking.

7.19.c
Only standard input specifiers and standard flags shall be used in input format
Synopsis
specifications.
Level 2

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 69/103
2024/11/27 下午4:24 ASML C Coding Standard

Category Library
Status Checked

Justification

The use of non-standard input specifiers or non-standard flags is not portable.

Example

scanf("%a", &i); /* WRONG */


scanf("%Li", &i); /* WRONG */
scanf("%Lo", &i); /* WRONG */
scanf("%Lu", &i); /* WRONG */
scanf("%Lx", &i); /* WRONG */
scanf("%he", &f); /* WRONG */
scanf("%hs", p); /* WRONG */
scanf("%hp", &v); /* WRONG */
scanf("%L%)"); /* WRONG */
scanf("%L[a]", p); /* WRONG */
scanf("%hc", &c); /* WRONG */
scanf("% i", &i); /* WRONG */
scanf("%[0-9]s", p); /* WRONG */
scanf("%[9-0]s", p); /* WRONG */
scanf("%.510%e", &d); /* WRONG */

7.19.d
The arguments in a formatted input function shall match the input specifiers in
Synopsis
the format specification.
Level 1
Category Library
Status Checked

Justification

Execution leads to undefined results when an input specifier and argument type do not match.

Example

scanf("%i", &f); /* WRONG */


scanf("%o", i); /* WRONG */
scanf("%[aa]s", p); /* WRONG */

7.19.e

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 70/103
2024/11/27 下午4:24 ASML C Coding Standard

The number of arguments to printf formats should correspond to the actual


Synopsis
arguments.
Level 1
Category Library
Status Unchecked

Justification

Execution leads to undefined results when the number of output specifiers and arguments do
not match.

Example

printf("There are %d people in total", people, total); /* WRONG */

7.19.f
Synopsis Do not access members of type FILE directly.
Level 6
Category Library
Status Checked

Justification

The FILE struct can be different on different operating systems. Source code should not depend
on the member fields. Programs that access for instance the "_fileno" field directly are in risk of
accessing another file descriptor and causing unpredictable harm to the system (write to
another file, close another file or socket, etc.). Use the available functions for FILE instead.
Examples of such functions are fopen(), fclose(), fread(), fwrite(), fflush(), fgetline(), fseek(),
fscanf(), fgets(), fgetc(), etc.

Example

FILE * f = fopen("/tmp/test", "w");


unsigned char c_lookahead = *f->_ptr; /* WRONG: not portable */
printf("file descriptor number: %d\n", f->_fileno); /* WRONG: not portable */
long pos = ftell(f); /* RIGHT */

7.19.g
Do not use the same buffer for reading and writing when calling input/output
Synopsis
functions.
Level 1

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 71/103
2024/11/27 下午4:24 ASML C Coding Standard

Category Library
Status Checked

Justification

If the same buffer is used the behavior is undefined.

Example

result = snprintf(mystring, STR_SIZE, "%s\n", mystring); /* WRONG */


result = snprintf(mynewstring, STR_SIZE, "%s\n", mystring); /* RIGHT */

7.21.a
Don't use the functions strerror and strtok, instead use their re-entrant
Synopsis
counterparts strerror_r and strtok_r.
Level 4
Category Library
Status Checked

Justification

Non-reentrant functions can cause problems when multiple threads are used or memory is
shared between tasks.

Example

token = strtok(string, delimiters); /* WRONG */


token = strtok(NULL, delimiters); /* WRONG */

char *save_ptr;
token = strtok_r(string, delimiters, &save_ptr); /* RIGHT */
token = strtok_r(NULL, delimiters, &save_ptr); /* RIGHT */

7.23.a
Don't use the functions asctime, ctime and gmtime instead use their re-entrant
Synopsis
counterparts asctime_r, ctime_r and gmtime_r.
Level 5
Category Library
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 72/103
2024/11/27 下午4:24 ASML C Coding Standard

Non re-entrant functions can cause problems when multiple threads are used or memory is
shared between tasks.

Example

char *datestring;
datestring = asctime(&tm); /* WRONG */

char datebuffer[MIN_BUFFER_SIZE]; /* statically allocated */


char *datestring;
datestring = asctime_r(&tm, datebuffer); /* RIGHT */

7.26.1.a
Synopsis Don't use the functions readdir instead use the re-entrant counterpart readdir_r
Level 5
Category Library
Status Checked

Justification

Non-reentrant functions can cause problems when multiple threads are used or memory is
shared between tasks (such as on VxWorks).

Example

#include <sys/types.h>
#include <dirent.h>

struct dirent *readdir(DIR *dirp); /* WRONG */


struct dirent *readdir_r(DIR *dirp, struct dirent *entry); /* RIGHT */

7.26.2.a
Synopsis Don't use the functions rand. Instead use the re-entrant counterpart rand_r.
Level 5
Category Library
Status Checked

Justification

Non-reentrant functions can cause problems when multiple threads are used or memory is
shared between tasks (such as on VxWorks).

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 73/103
2024/11/27 下午4:24 ASML C Coding Standard

#include <stdlib.h>

int rand(void); /* WRONG */


int rand_r(unsigned *seed); /* RIGHT */

Note

Function rand_r is not available on VxWorks in kernel space.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 74/103
2024/11/27 下午4:24 ASML C Coding Standard

Preprocessing Directives
6.10.a
Use of pre-processor directives shall be according to strict ANSI syntax and
Synopsis
constraints.
Level 2
Category Preprocessing Directives
Status Checked

Justification

Use of the pre-processor directive with a syntax other than defined by ANSI might be acceptable
for a certain pre-processor but delivers an undefined or at least non-portable source to the
compiler's translation phase.

6.10.b
Synopsis Only perform token pasting with the token pasting operator (##).
Level 8
Category Preprocessing Directives
Status Checked

Justification

ANSI C provides the ## operator as a portable alternative to implementation specific forms of


token pasting.

Example

#define fullname(comp, func) comp ## func /* RIGHT */


#define fullname(comp, func) comp/**/func /* WRONG */

fullname(COMPONENTX_, set_shape)

6.10.1.a
Synopsis Code checker flags shall not be used in the source code.
Level 6
Category Preprocessing Directives
Status Checked
Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 75/103
2024/11/27 下午4:24 ASML C Coding Standard

#ifdef TICS /* WRONG */

6.10.1.c
#ifdef, #ifndef, #if defined and #if !defined are not allowed in external header
Synopsis
files.
Level 3
Category Preprocessing Directives
Status Checked

Justification

Defining code in external header files makes the inclusion very error-prone.

Exceptions:

Multiple include guards


__cplusplus
Cases where compile time checking is critical in preventing calls from one compiler platform
to another

6.10.1.e
Synopsis Don't use "#if 0" as comments
Level 7
Category Preprocessing Directives
Status Checked
Using "#if 0" as comments has at least 2 disadvantages:

The "#if 0" construction is most often used to comment out code. Commenting out code is
not recommended because it is not clear why it is commented out. Should it be
commented in again at a later stage? Possibly it won't even compile at that time any more.
The configuration management system should be used in that case to keep track of code
that is (temporarily) not needed any more.
Most editors won't highlight code within "#if 0" as comments and it is hard to recognize for
human beings that it doesn't concern real code.

Example:

#if 0
if (status > 0) {
return error;
}
#endif

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 76/103
2024/11/27 下午4:24 ASML C Coding Standard

6.10.2.a
Synopsis All headers files shall be identified by an #include directive.
Level 2
Category Preprocessing Directives
Status Checked

Justification

Because "include <>" also searches system directories while "include """ doesn't, we shall use
"#include <>" for inclusion of system header files (such as stdio.h). For other files "#include """
shall be used. Using (absolute) paths is a cause of build errors in a complex and/or flexible build
environment.

Example

#include <stdio.h> /* RIGHT: System Includes */


#include "own_lib.h" /* RIGHT: Own Component Includes */
#include " somefile.h" /* WRONG: extra space */
#include"somefile.h" /* WRONG: missing space */
#include "../any_header_file.h" /* WRONG: do not use .. */

6.10.2.b
Synopsis Including source files is not allowed.
Level 6
Category Preprocessing Directives
Status Checked

Justification

When including a source file, all its elements are included, such as local variables. This leads to
name clashes and unpredictable behavior.

Example

#include "status.c" /* WRONG */

6.10.2.c
Synopsis It is forbidden to include hpp files in C files.
Level 5
Category Preprocessing Directives
Status Checked

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 77/103
2024/11/27 下午4:24 ASML C Coding Standard

Justification

The file extension "hpp" is reserved for C++ header files only. By including a file with extension
"hpp" in a C file, the header file itself will also become a C file because it will be compiled by the
C compiler.

Example

#include "KwShMem.hpp" /* WRONG */


#include "KwShMem.h" /* RIGHT */

6.10.3.a
Use of macros shall strictly be according to the ANSI C89 macro syntax and within
Synopsis
the ANSI C89 macro constraints.
Level 2
Category Preprocessing Directives
Status Unchecked

Justification

Use of macros other than within the strict ANSI C89 syntax and constraints may be acceptable
for a certain pre-processor but delivers an undefined or at least non-portable source to the
compiler's translation phase.

Example

#define PLAK(a ,b) a ## b


/* ... */
#define PLAK (1) /* WRONG: redefines PLAK */

#define STR(text) #text


/* ... */
char *msg = STR(error, "\n"); /* WRONG: too many arguments */

6.10.3.b
Synopsis #define macros shall only be used for symbolic constants.
Level 2
Category Preprocessing Directives
Status Checked

6.10.3.c

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 78/103
2024/11/27 下午4:24 ASML C Coding Standard

Any instance of macro parameters, macro body and macro operations shall be
Synopsis
enclosed within parenthesis.
Level 8
Category Preprocessing Directives
Status Checked

Justification

Omitting parenthesis around macro parameters, macro body or macro operations can lead to
unexpected interpretation of the source code.

Example 1

#define C A + B /* WRONG */

x = 3 * C; /* this would evaluate to 3*A + B */

Example 2

#define C (A + B) /* RIGHT */

x = 3 * C; /* this evaluates to 3*(A + B) */

Example 3

#define NOK 1 /* RIGHT */


#define GOOD (-1) /* RIGHT */
#define SQUARE(a) ((a) * (a)) /* RIGHT */

#define BAD -1 /* WRONG */


#define AWFUL(a,b) a * b /* WRONG */

x = AWFUL(1 + 1, 1) * 4; /* looks like 8... */


x = 1 + 1 * 1 * 4; /* ... but is 5 instead */

6.10.3.d
Synopsis Macros should not end with a semicolon.
Level 6
Category Preprocessing Directives
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 79/103
2024/11/27 下午4:24 ASML C Coding Standard

If a macro definition ends with a semicolon, the macro caller can't use a semicolon after the
macro, otherwise there will be 2 semicolons after macro expansion. Most compilers and code
checkers will consider this extra semicolon as an empty statement and warn about it. The macro
caller should use the semicolon because that makes code much easier to read and maintain.

Example

#define PTR_SANITY_CHECK( ptr ) \ /* macro definition */

ASSERT(r, PARAMETER_ERROR, ( ptr != NULL)); /* WRONG */

ASSERT(r, SOME_ERROR, TRUE) /* call in the code */

#define PTR_SANITY_CHECK( ptr ) \ /* macro definition */

ASSERT(r, PARAMETER_ERROR, ( ptr != NULL)) /* RIGHT */

ASSERT(r, SOME_ERROR, TRUE); /* call in the code */

6.10.3.e
Synopsis Use a semicolon at the end of a function-like macro call.
Level 6
Category Preprocessing Directives
Status Checked

Justification

The macro caller should use a semicolon to make code much easier to read and maintain.

Example

ASSERT(r, SOME_ERROR, TRUE) /* WRONG */


ASSERT(r, SOME_ERROR, TRUE); /* RIGHT */

6.10.3.2.b
Synopsis A macro shall not comprise both the "#" and "##" operators simultaneously.
Level 2
Category Preprocessing Directives
Status Checked

Justification

The order of evaluation when the "#" and "##" operators are used together is undefined.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 80/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

#define debug(s) printf("x" #s "= %d\n", x ## s)

/* WRONG: The order in which the # and ## operators are evaluated is


* unspecified by the C standard.
*/

6.10.3.3.a
Synopsis Result of "##" operator shall be a legal pre-processing token.
Level 2
Category Preprocessing Directives
Status Checked

Justification

The "##" operator should be used sparingly and with care. In particular there are constraints
which operate on the context in which it may be used. The result of the glue operator should be
a valid pre-processing token; so it is not legal, for instance, to glue together an operator to an
identifier. Valid pre-processing tokens must have the lexical form of a header-name, an
identifier, a character constant, a string literal, an operator, a punctuator or any non-white-space
character that cannot be one of the above.

Example 1

#define Select(a) (xxx_struct.##a) /* WRONG: The "." is a separate token */

Example 2

#define Select(a) (xxx_struct.a) /* RIGHT */

6.10.3.4.a
Synopsis Recursive macro definitions shall not be used.
Level 4
Category Preprocessing Directives
Status Checked

Justification

Recursive macro definitions are not replaced. Nested replacement of the macro name being
replaced is not carried out.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 81/103
2024/11/27 下午4:24 ASML C Coding Standard

6.10.3.5.a
Synopsis Macros shall only be #define'd and #undef'ed at file scope.
Level 4
Category Preprocessing Directives
Status Checked

Justification

Although macro names are not affected by the C scoping rules, using #define inside a C scope
looks very confusing - programmers tend to forget that such macros are still accessible outside
that scope.

Example

void f(void)
{
int i = 0;
int j = 0;
...
#define MIN_VAL 4 /* WRONG */
...
}

6.10.4.a
The line splicing character ('\' at the end of a line) shall not be used, except in
Synopsis
preprocessor macros.
Level 8
Category Preprocessing Directives
Status Checked

Justification

This construct does not enhance readability in for example string literals. It also prohibits
indentation in string literals.

Example 1

const char message[] = "This is a string on more than \


one line.\n"; /* WRONG */

const char message[] = "This is a string on more than "


"one line.\n"; /* RIGHT */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 82/103
2024/11/27 下午4:24 ASML C Coding Standard

Example 2

#define VERY_LONG_MACRO_NAME \
(...) /* RIGHT */

6.10.4.b
When used, the line-splicing character ('\' at the end of a line) shall immediately
Synopsis
be followed by the newline character.
Level 6
Category Preprocessing Directives
Status Checked

Justification

This avoids undefined behavior according to the C standard. Characters following the line-
splicing character might break tools that can't handle this. For example, the CScout tool has
problems with trailing spaces, thus resulting in partial cross reference data.

Example

#define DEFINE_VERY_LONG_MACRO_NAME \ /* comment */


1234 /* WRONG */

#define DEFINE_VERY_LONG_MACRO_NAME \
1234 /* RIGHT */

6.10.4.c
Synopsis Do not use mixed EOL characters in a file.
Level 8
Category Preprocessing Directives
Status Checked

Justification

Some tools have problems with files that have different line endings, e.g. mixing Linux and
Windows end of line characters.

6.10.6.a
Synopsis The pragma directive and pragma operator shall not be used.
Level 2
Category Preprocessing Directives

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 83/103
2024/11/27 下午4:24 ASML C Coding Standard

Status Checked

Justification

The behavior of #pragma and _Pragma are implementation defined and non-portable.

6.10.8.b
Synopsis Only the predefined macro names __FILE__, __LINE__ and __func__ may be used.
Level 3
Category Preprocessing Directives
Status Checked

Justification

Portability.

Example

printf("Filename: %s function: %s line: %d\n",


__FILE__, __func__, __LINE__); /* RIGHT */

Note

__func__ is a C99 extension and is only portable between C99 (and higher) compilers.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 84/103
2024/11/27 下午4:24 ASML C Coding Standard

Statement and Blocks


6.8.a
All control statements shall be fully brace enclosed. This means that all "if",
Synopsis "while", "for", "do" and "switch" statements are followed by a brace-enclosed
compound statement.
Level 5
Category Statement and Blocks
Status Checked

Justification

By using braces a visible grouping of statements is created. Programming errors can be caused
when the body of a control statement without braces is expanded from one statement to many.

Example 1

if (...)
if (...) /* WRONG */
{
...
}
else /* This "else" belongs to the second "if" and not to the first "if".*/
{
...
}

Example 2

if (...)
{ /* RIGHT */
if (...)
{
...
}
}
else
{
...
}

6.8.c
Synopsis Any statement that is logically never executed shall not occur in the source code.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 85/103
2024/11/27 下午4:24 ASML C Coding Standard

Level 3
Category Statement and Blocks
Status Checked

Justification

Unused statements add to program complexity just by being there - adding lines to a program
and causing readers to puzzle over its presence.

6.8.d
Synopsis Avoid magic numbers.
Level 8
Category Statement and Blocks
Status Checked

Justification

Do not use hard-coded numbers. It is better practice to use a macro constant or a typed
constant (e.g. "const float"); these can be defined in an appropriate location where they can be
easily reviewed and maintained. Furthermore, typed constants have the benefit of allowing the
compiler to check their type.

Example 1

#define CCBB_SPEED_LIMIT 1.50137


const int OTHER_LIMIT = 3.8014;

void CCBB_func(double d);

void CCBB_fn(void)
{
CCBB_func(1.50137); /* WRONG: hard-coded number used */

CCBB_func(CCBB_SPEED_LIMIT); /* RIGHT */
CCBB_func(OTHER_LIMIT); /* RIGHT */
}

Example 2

/* Root finding second order equation */


r0 = (-b + sqrt(b * b - 4.0 * a * c) ) / (2.0 * a); /* RIGHT: this will not change */

Example 3

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 86/103
2024/11/27 下午4:24 ASML C Coding Standard

/* Check if FOUP is full */


i = 0; /* RIGHT: indexing always starts at 0 */
full = TRUE;

while (full && (i < 25)) /* WRONG: usage of magic number 25 */


{
if (my_FOUP[i] == has_no_wafer)
{
full = FALSE;
}
i++;
}

6.8.1.a
Statements shall not be labelled except for "case" and "default" in a switch-
Synopsis
statement.
Level 3
Category Statement and Blocks
Status Checked

Justification

The only reason for using a labeled statement is to jump to it. Such jumps are forbidden.

Example

L1:i = 10; /* WRONG */


L1:i = 20; /* WRONG */
T :i = 30; /* WRONG */

6.8.3.a
Synopsis Each expression and statement shall have an effect.
Level 6
Category Statement and Blocks
Status Checked

Justification

Specified expressions that cause no effect clutter the program text, leaving the puzzle why the
expression or statement is there to the reader.

Example

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 87/103
2024/11/27 下午4:24 ASML C Coding Standard

i == 1; /* WRONG: "i" has no effect. */


j + 1; /* WRONG: "j" has no effect. */

i = 1; /* RIGHT */
n = j + 1; /* RIGHT */

6.8.3.b
Synopsis An empty statement shall not be used.
Level 6
Category Statement and Blocks
Status Checked

6.8.4.b
The condition (or guard) of a selective alternative shall be a logical operator, an
Synopsis equality operator or a relational expression (and not be an assignment). Exception
is made for boolean type. For boolean type no relational expression is required.
Level 6
Category Statement and Blocks
Status Checked

Justification

Example 1

if (i = a) /* WRONG: assignment as well as a test */


{
/* Any statement */
}

Example 2

if (i) /* WRONG */
{
/* Any statement */
}

Example 3

if (i == 1) /* RIGHT: equality operator */


{
/* Any statement */
}

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 88/103
2024/11/27 下午4:24 ASML C Coding Standard

Example 4

if (fp = fopen("TMP", "r")) /* WRONG */


{
/* Any statement */
}

Example 5

if (!(fp = fopen("TMP", "r"))) /* WRONG */


{
/* Any statement */
}

Example 6

fp = fopen("TMP", "r");

if (fp != NULL) /* RIGHT */


{
/* Any statement */
}

Example 7

bool doorclosed(void);

if (doorclosed() == true) /* WRONG */


{
/* Any statement */
}

Example 8

bool doorclosed(void);

if (doorclosed()) /* RIGHT: by exception */


{
/* Any statement */
}

6.8.4.c
Synopsis The termination condition of iterations shall be of type boolean.
Level 7

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 89/103
2024/11/27 下午4:24 ASML C Coding Standard

Category Statement and Blocks


Status Unchecked

Justification

Conditions are meant to test boolean values, not integers, characters, pointers or other types. In
the latter cases, C will implicitly convert the type into a boolean, which might lead to unintended
behavior.

Example 1

#include <string.h>

static const char *ccbb_s[] =


{
"Hello",
"World",
NULL
};

static int ccbb_f(void)


{
int i = 0;
bool found = false;

while ((ccbb_s[i] != NULL) && !found) /* RIGHT */


{
found = (strcasecmp(ccbb_s[i], "World") != 0);
i++;
}
...

Example 2

while (strcasecmp(ccbb_s[i], "World")) /* WRONG: strcasecmp() returns int */

6.8.4.1.b
N-ary selection constructs programmed using "if ... else if ..." shall have an "else"
Synopsis
clause.
Level 6
Category Statement and Blocks
Status Checked

Justification

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 90/103
2024/11/27 下午4:24 ASML C Coding Standard

In the interest of safety and reliability an "else" clause should always be included to be sure all
possible cases are covered.

Example 1

if (temp < 0)
{
/* any statement */
}
else if (temp > 0)
{
/* any statement */
} /* WRONG */

Example 2

if (temp < 0)
{
/* any statement */
}
else if (temp > 0)
{
/* any statement */
}
else /* temp == 0 */ /* RIGHT */
{
/* Log an error */
}

Note

It is best practice to use the last "else" clause to log an error even (or especially) if one should
never get there.

6.8.4.2.a
The switch expression shall not contain any logical expression (one or more of the
Synopsis
">", ">=", "<", "<=", "==", "!=", "&&", "||" or "!" operators).
Level 5
Category Statement and Blocks
Status Checked

Justification

Using relational or logical operators in a "switch" expression is very likely to be wrong and is at
best confusing. Consider the use of an "if" statement.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 91/103
2024/11/27 下午4:24 ASML C Coding Standard

Example

#define CCBB_THE_CHOICE 1
switch (option == pick) /* WRONG */
{
case CCBB_THE_CHOICE:
/* any statement */
break;
default:
/* any statement */
break;
}

6.8.4.2.b
Synopsis "switch" statements shall have one and only one "default" clause.
Level 2
Category Statement and Blocks
Status Checked

Justification

Defensive programming dictates that multiple choice constructs have a guard (condition), to
trap "impossible" errors. Since the default action is a "catch-all" it aids the reader to enumerate
the possible special cases before the general case.

Exception: If a case clause is present for each of the possible values of an enum type, a default
clause is not required.

Example 1

#define CCBB_THE_CHOICE 1

int trigger;

trigger = 2;
switch (trigger)
{
case CCBB_THE_CHOICE:
break;
} /* WRONG: Default clause is missing */

Example 2

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 92/103
2024/11/27 下午4:24 ASML C Coding Standard

#define CCBB_THE_CHOICE 1

int trigger;
...
switch (trigger)
{
case CCBB_THE_CHOICE:
break;
default: /* RIGHT */
/* any statement */
break;
}

Example 3

enum Colors {Red, Blue, Green} color;

color = Red;
switch (color)
{
case Red:
break;
case Blue:
break;
case Green:
break;
} /* RIGHT: no default clause required because all enum values are covered. */

6.8.4.2.c
Synopsis Each non empty case clause and default clause shall end with a break statement.
Level 2
Category Statement and Blocks
Status Checked

Justification

Allowing "case" clauses to fall-through into each other is a confusing practice - if two (or more)
clauses share common tail code, that should be made explicit by making the tail code a function
and calling it from each of the clauses that requires it.

Example 1

switch (trigger)
{

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 93/103
2024/11/27 下午4:24 ASML C Coding Standard

case 1:
case 2:
/* do something */
break; /* RIGHT */
default: /* WRONG */
}

Example 2

switch (trigger)
{
case 4:
i = 10; /* WRONG */
case 5:
default:
break;
}

6.8.4.2.d
Synopsis The default clause shall be the last entry in the switch statement.
Level 5
Category Statement and Blocks
Status Checked

Justification

In the interest of readability.

Example 1

switch (option)
{
default: /* WRONG */
/* any statement */
break;
case 1:
/* any statement */
break;
}

Example 2

switch (option)
{
case 1: /* RIGHT */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 94/103
2024/11/27 下午4:24 ASML C Coding Standard

/* any statement */
break;
default:
/* any statement */
break;
}

6.8.4.2.e
Synopsis Make sure all code in a switch statement serves a purpose.
Level 6
Category Statement and Blocks
Status Checked

Justification

The code before the first "case" label can never be executed and clutters the program text.

Example 1

switch (i)
{
int k = 0; /* WRONG: initializations are not possible */
i = i + 1; /* this next statement is never executed */
case 1:
/* any statement */
break;
case 2:
/* any statement */
break;
default:
{
/* ... */
}
}

Example 2

switch (i) /* A Switch with only one case. Better use if */


{
case 1:
/* any statement */
break;
default:
{
/* ... */

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 95/103
2024/11/27 下午4:24 ASML C Coding Standard

}
}

6.8.5.a
Synopsis The termination condition of iteration shall not have a constant value.
Level 4
Category Statement and Blocks
Status Checked

Justification

Avoid unintended dead code or infinite loops.

Example 1

#define TEST (false)

while (TEST) /* WRONG */


{
/* Any statement */
}

Example 2

#define TEST (false)

for (i = 0; TEST; i++) /* WRONG */


{
/* Any statement */
}

Example 3

/* infinite loop */
for (;;) /* RIGHT */
{
/* Any statement */
}

Note

When an infinite loop is needed use for (;;) instead.

An exception is made for the "do {} while (0)" construct used in header files for macros.

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 96/103
2024/11/27 下午4:24 ASML C Coding Standard

6.8.5.1.a
The variables used in expression 2 of a "for" loop shall not be changed in the loop
Synopsis
body and expression 3 at the same time.
Level 6
Category Statement and Blocks
Status Checked

Justification

Example 1

for (i = 0; (text[i] != '\0') && (e == OK); i++) /* RIGHT */


{
/* Any statement */
e = f();
/* Any statement */
}

Example 2

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


{
/* Any statement */
i++; /* WRONG */
/* Any statement */
}

Example 3

for (a = 0; text[a] != '\0'; a++)


{
b = a;
...a...b... /* RIGHT */
}

6.8.5.1.c
Synopsis The loop variable of a for loop shall be used in the loop body.
Level 8
Category Statement and Blocks
Status Checked

6.8.6.1.a

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 97/103
2024/11/27 下午4:24 ASML C Coding Standard

Synopsis The "goto" statement shall not be used.


Level 6
Category Statement and Blocks
Status Checked

Justification

Use of the "goto" statement is unstructured and can always be avoided by properly structuring
the flow of control.

Example

goto label;
label:
i++; /* WRONG */

6.8.6.2.a
Synopsis The "continue" statement shall not be used.
Level 6
Category Statement and Blocks
Status Checked

Justification

"continue" statements cause breaks in the normal structured control flow of a program. For this
reason they shall be avoided as they affect the readability and maintainability of the code.

Example 1

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


{
if (a[i] < 0)
{
/* process negative term */
continue; /* WRONG */
}
/* Process positive term */
}

Example 2

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


{
if (a[i] < 0)

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 98/103
2024/11/27 下午4:24 ASML C Coding Standard

{
/* Process negative term */
}
else /* a[i] >= 0 */ /* RIGHT */
{
/* Process positive term */
}
}

6.8.6.4.a
Synopsis There shall be exactly one "return" statement in a function returning non-void.
Level 9
Category Statement and Blocks
Status Checked

Justification

More than one exit point indicates a forced break in control flow and, like any break in control
flow, leads to code which is more difficult to read and maintain.

Example 1

if (i > 10)
{
return (i - 10); /* WRONG */
}
else
{
return (i); /* WRONG */
}

Example 2

var result = 0;

...

if (i > 10)
{
result = i - 10;
}
else
{
result = i;
}

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xFI… 99/103
2024/11/27 下午4:24 ASML C Coding Standard

return result; /* RIGHT */

Exception

Multiple returns are allowed in case of simple (failing) tests at the beginning of a function. This is
called the fail-fast pattern.

Note

Do not confuse an exit function call with a "return" statement: a "return" statement is to return
to its caller, where an exit statement is to terminate the program execution.

6.8.6.4.b
Synopsis There shall be no return statement in a void function.
Level 9
Category Statement and Blocks
Status Checked

Justification

There is no need for a return statement in a void function. Absence of a return statement
prevents adding an expression to the return statement.

Example 1

void f(void)
{
/* any statement */
return (i); /* WRONG */
}

Example 2

void f(void)
{
/* any statement */
/* no return statement */ /* RIGHT */
}

6.8.6.4.c
Synopsis A function "return" expression shall be compatible with its explicitly defined type.
Level 2

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xF… 100/103
2024/11/27 下午4:24 ASML C Coding Standard

Category Statement and Blocks


Status Checked

Justification

Using non-compatible return expressions leads to undefined behavior when the function is
used.

Example 1

float f(void)
{
int i = 0;
...
return; /* WRONG */
}

Example 2

void f(void)
{
return (0); /* WRONG */
}

6.8.6.4.d
Synopsis Function return values that are error codes shall not be ignored.
Level 6
Category Statement and Blocks
Status Checked

Justification

If you ignore an error code and an error occurs, it will be very hard to find the root cause.

Example 1

static int ccbb_example(void)


{
/* log error code */
return e;
}

void CCBB_X(void)
{

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xF… 101/103
2024/11/27 下午4:24 ASML C Coding Standard

ccbb_example(); /* WRONG: return value is ignored */


}

Example 2

static int ccbb_example(void)


{
return (e);
}

void CCBB_X(void)
{
if (ccbb_example() == OK) /* RIGHT */
{
...
}
}

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xF… 102/103
2024/11/27 下午4:24 ASML C Coding Standard

Literature

https://csviewer.tiobe.com/#/ruleset/rules?status=CHECKED,UNCHECKED&tagid=Tou5vbm9Rq6hEVnTQDykww&setid=j3EhCYp3T1-J36xF… 103/103

You might also like