asml c coding standard

110
ASML C Coding Standard Version: head

Upload: others

Post on 22-May-2022

36 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: ASML C Coding Standard

ASML C Coding StandardVersion: head

Page 2: ASML C Coding Standard

Table of ContentsChange History..................................................................................................................................................1

Introduction........................................................................................................................................................2Scope.......................................................................................................................................................2

Conceptual Models............................................................................................................................................4Rule 5.1.1.b.............................................................................................................................................4Rule 5.1.1.c.............................................................................................................................................5Rule 5.1.1.d.............................................................................................................................................6Rule 5.1.1.f..............................................................................................................................................6Rule 5.1.1.1.b..........................................................................................................................................7Rule 5.1.1.1.c..........................................................................................................................................7Rule 5.1.1.2.b..........................................................................................................................................8Rule 5.1.2.b.............................................................................................................................................8Rule 5.1.2.3.a..........................................................................................................................................9Rule 5.1.2.3.b........................................................................................................................................10

Environmental Considerations.......................................................................................................................12Rule 5.2.1.1.b........................................................................................................................................12

Concepts............................................................................................................................................................13Rule 6.2.2.b...........................................................................................................................................13Rule 6.2.2.c...........................................................................................................................................13Rule 6.2.3.a...........................................................................................................................................14Rule 6.2.4.b...........................................................................................................................................14Rule 6.2.5.a...........................................................................................................................................15

Conversions......................................................................................................................................................17Rule 6.3.a..............................................................................................................................................17Rule 6.3.b..............................................................................................................................................18Rule 6.3.1.a...........................................................................................................................................19Rule 6.3.2.1.a........................................................................................................................................19Rule 6.3.2.2.a........................................................................................................................................20Rule 6.3.2.2.b........................................................................................................................................21Rule 6.3.2.2.c........................................................................................................................................21Rule 6.3.2.2.d........................................................................................................................................22Rule 6.3.2.2.e........................................................................................................................................22Rule 6.3.2.3.a........................................................................................................................................23Rule 6.3.2.3.d........................................................................................................................................24

Lexical Elements..............................................................................................................................................25Rule 6.4.b..............................................................................................................................................25Rule 6.4.1.a...........................................................................................................................................26Rule 6.4.1.b...........................................................................................................................................26Rule 6.4.1.1.a........................................................................................................................................27Rule 6.4.1.1.b........................................................................................................................................28Rule 6.4.2.a...........................................................................................................................................28Rule 6.4.2.b...........................................................................................................................................29Rule 6.4.2.d...........................................................................................................................................29Rule 6.4.4.b...........................................................................................................................................30Rule 6.4.4.1.a........................................................................................................................................30Rule 6.4.4.1.b........................................................................................................................................30

title

i

Page 3: ASML C Coding Standard

Table of ContentsLexical Elements

Rule 6.4.4.3.a........................................................................................................................................31Rule 6.4.4.4.a........................................................................................................................................31Rule 6.4.5.a...........................................................................................................................................32Rule 6.4.9.a...........................................................................................................................................32Rule 6.4.9.c...........................................................................................................................................33

Expressions.......................................................................................................................................................34Rule 6.5.a..............................................................................................................................................35Rule 6.5.2.1.a........................................................................................................................................35Rule 6.5.2.1.b........................................................................................................................................36Rule 6.5.2.2.b........................................................................................................................................36Rule 6.5.2.2.c........................................................................................................................................37Rule 6.5.2.3.a........................................................................................................................................37Rule 6.5.2.3.b........................................................................................................................................38Rule 6.5.2.3.d........................................................................................................................................38Rule 6.5.3.1.a........................................................................................................................................39Rule 6.5.3.1.b........................................................................................................................................39Rule 6.5.3.2.a........................................................................................................................................40Rule 6.5.3.3.a........................................................................................................................................41Rule 6.5.3.3.b........................................................................................................................................41Rule 6.5.3.4.a........................................................................................................................................42Rule 6.5.3.4.b........................................................................................................................................42Rule 6.5.3.4.c........................................................................................................................................43Rule 6.5.4.a...........................................................................................................................................43Rule 6.5.7.b...........................................................................................................................................43Rule 6.5.8.a...........................................................................................................................................44Rule 6.5.8.c...........................................................................................................................................44Rule 6.5.8.d...........................................................................................................................................45Rule 6.5.8.e...........................................................................................................................................45Rule 6.5.8.f............................................................................................................................................46Rule 6.5.9.a...........................................................................................................................................47Rule 6.5.9.b...........................................................................................................................................47Rule 6.5.13.a.........................................................................................................................................49Rule 6.5.15.a.........................................................................................................................................49Rule 6.5.16.a.........................................................................................................................................50Rule 6.5.16.b.........................................................................................................................................51Rule 6.5.17.a.........................................................................................................................................51

Declarations......................................................................................................................................................52Rule 6.7.a..............................................................................................................................................52Rule 6.7.1.a...........................................................................................................................................53Rule 6.7.1.b...........................................................................................................................................53Rule 6.7.1.c...........................................................................................................................................53Rule 6.7.2.a...........................................................................................................................................54Rule 6.7.2.b...........................................................................................................................................54Rule 6.7.2.1.a........................................................................................................................................55Rule 6.7.2.2.a........................................................................................................................................55Rule 6.7.3.a...........................................................................................................................................56Rule 6.7.5.a...........................................................................................................................................56Rule 6.7.5.2.a........................................................................................................................................57Rule 6.7.5.3.a........................................................................................................................................58

title

ii

Page 4: ASML C Coding Standard

Table of ContentsDeclarations

Rule 6.7.5.3.b........................................................................................................................................58Rule 6.7.5.3.c........................................................................................................................................59Rule 6.7.8.a...........................................................................................................................................59Rule 6.7.8.b...........................................................................................................................................60Rule 6.7.8.c...........................................................................................................................................61Rule 6.7.8.d...........................................................................................................................................61

Statement and Blocks......................................................................................................................................63Rule 6.8.a..............................................................................................................................................63Rule 6.8.c..............................................................................................................................................64Rule 6.8.d..............................................................................................................................................65Rule 6.8.1.a...........................................................................................................................................65Rule 6.8.3.a...........................................................................................................................................66Rule 6.8.3.b...........................................................................................................................................66Rule 6.8.4.b...........................................................................................................................................67Rule 6.8.4.c...........................................................................................................................................68Rule 6.8.4.1.b........................................................................................................................................69Rule 6.8.4.2.a........................................................................................................................................70Rule 6.8.4.2.b........................................................................................................................................71Rule 6.8.4.2.c........................................................................................................................................72Rule 6.8.4.2.d........................................................................................................................................72Rule 6.8.4.2.e........................................................................................................................................73Rule 6.8.5.a...........................................................................................................................................74Rule 6.8.5.1.a........................................................................................................................................75Rule 6.8.5.1.c........................................................................................................................................75Rule 6.8.6.1.a........................................................................................................................................76Rule 6.8.6.2.a........................................................................................................................................76Rule 6.8.6.3.a........................................................................................................................................77Rule 6.8.6.4.a........................................................................................................................................78Rule 6.8.6.4.b........................................................................................................................................79Rule 6.8.6.4.c........................................................................................................................................79Rule 6.8.6.4.d........................................................................................................................................80

External Definitions.........................................................................................................................................81Rule 6.9.1.a...........................................................................................................................................81Rule 6.9.1.b...........................................................................................................................................82Rule 6.9.2.a...........................................................................................................................................82Rule 6.9.2.b...........................................................................................................................................83

Preprocessing Directives.................................................................................................................................84Rule 6.10.a............................................................................................................................................84Rule 6.10.b............................................................................................................................................85Rule 6.10.1.a.........................................................................................................................................85Rule 6.10.1.c.........................................................................................................................................85Rule 6.10.1.e.........................................................................................................................................86Rule 6.10.2.a.........................................................................................................................................86Rule 6.10.2.b.........................................................................................................................................87Rule 6.10.2.c.........................................................................................................................................87Rule 6.10.3.a.........................................................................................................................................88Rule 6.10.3.b.........................................................................................................................................88Rule 6.10.3.c.........................................................................................................................................89

title

iii

Page 5: ASML C Coding Standard

Table of ContentsPreprocessing Directives

Rule 6.10.3.d.........................................................................................................................................90Rule 6.10.3.e.........................................................................................................................................91Rule 6.10.3.2.b......................................................................................................................................91Rule 6.10.3.3.a......................................................................................................................................91Rule 6.10.3.4.a......................................................................................................................................92Rule 6.10.3.5.a......................................................................................................................................92Rule 6.10.4.a.........................................................................................................................................93Rule 6.10.4.b.........................................................................................................................................93Rule 6.10.4.c.........................................................................................................................................94Rule 6.10.6.a.........................................................................................................................................94Rule 6.10.8.b.........................................................................................................................................95

Library ..............................................................................................................................................................96Rule 7.2.a..............................................................................................................................................96Rule 7.12.a............................................................................................................................................96Rule 7.12.b............................................................................................................................................97Rule 7.13.a............................................................................................................................................98Rule 7.18.a............................................................................................................................................98Rule 7.19.a............................................................................................................................................99Rule 7.19.b............................................................................................................................................99Rule 7.19.c..........................................................................................................................................100Rule 7.19.d..........................................................................................................................................101Rule 7.19.e..........................................................................................................................................101Rule 7.19.f...........................................................................................................................................101Rule 7.19.g..........................................................................................................................................102Rule 7.21.a..........................................................................................................................................102Rule 7.23.a..........................................................................................................................................103Rule 7.26.1.a.......................................................................................................................................103Rule 7.26.2.a.......................................................................................................................................104

Literature........................................................................................................................................................105

title

iv

Page 6: ASML C Coding Standard

Change HistoryRevision Date Description

18.6 2022-05-06 23:23:53 Paul Jansen (TIOBE):- PD-536: Added rule 6.7.5.3.c.

18.5 2022-04-28 10:50:49 Paul Jansen (TIOBE):- PD-578: Added rule 6.10.1.e.

18.4 2022-04-28 09:56:40 Paul Jansen (TIOBE):- PD-591: Improved the description of rule 5.1.1.b.

18.3 2022-01-31 14:05:41 Paul Jansen (TIOBE):- TiCS ticket 29717: Improved description of rule 5.1.1.b.

18.2 2022-01-18 12:28:40 Paul Jansen (TIOBE):- TiCS ticket 29716: Removed rule 6.10.1.d.

18.1 2022-01-11 23:14:15 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-29 23:52:55 Paul Jansen (TIOBE):- Published the first public version of the ASML C Coding Standard.

1

Page 7: ASML C Coding Standard

Introduction

This document defines a standard for the production of high quality C code, and consists of a number of rulesand 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 theuse of this base language to a subset satisfying the high quality issues as mentioned before. The restrictionsare chosen such that the subset contains no features that are open to interpretation, either by a compiler or byprogrammers.

Scope

This standard applies to all initiated software development projects (thus including outsourced C code). Thisstandard 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 compilerextensions supported by ISO C99 standard. The section arrangement has been kept similar to the C99standard.

Objectives of this standard

This standard aims to help developers in creating high quality C code. It therefore enforces best practices in Cdevelopment and prohibits use of a number of features of C known to lead to portability issues, because theyare unstructured or lead to unspecified, undefined or implementation-defined behavior. In each case ajustification 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 shallnot be fixed. From time to time this standard will be reviewed and updated to reflect the contemporary bestpractices in developing C code, enabling to continue with its policy of providing high quality C code thatrepresents the current state of the art.

Rules and levels

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

2

Page 8: ASML C Coding Standard

Disclaimer

This C-Coding Standard is provided "AS IS", without warranty of any kind and without indemnity of anykind, express or implied, including but not limited to the warranties of merchantability, fitness for a particularpurpose 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 inconnection with the C Coding Standard, the ue of the C Coding Standard or other dealings with the C Codingstandard. 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.

title 05/21/22

3

Page 9: ASML C Coding Standard

Conceptual ModelsAn implementation translates C source files and executes C programs in two data-processing-systemenvironments, which will be called the translation environment and the execution environment in thisdocument. Their characteristics define and constrain the results of executing conforming C programsconstructed according to the syntactic and semantic rules for conforming implementations.

Rules

5.1.1.b Each source file shall start with a file header, for which the "file name", "description" andcopyright notice are to be filled in.

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

5.1.1.d Only files that are really needed shall be included.

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

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

5.1.1.1.c Naming convention of the include guard of an include file named CCBB_foo.h is of format:CCBB_FOO_H

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

5.1.2.b Local variables shall not cause stack overflow.

5.1.2.3.a Side effects shall not be relied upon between successive sequence points.

5.1.2.3.b Expressions which mix operators from the set ">", ">=", ">", "^", "&", "|", "&&", "||" and whichuse two or more distinct operators from the latter set shall be fully parenthesized and shall notdepend on the C precedence rules.

Rule 5.1.1.b

Synopsis:Each source file shall start with a file header, for which the "file name", "description" andcopyright notice are to be filled in.

Language:CLevel: 8Category:Conceptual Models

Description

Justification

Enough information should be provided in the header to be able to understand the functionality withoutreading 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 rightto a new copyright, then that year should be mentioned too. The most important year is the first year.

4

Page 10: ASML C Coding Standard

When a SW developer encounters copyright statements in existing source files that are old or wrong, thenthey 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: ||-------------------------------------------------------------------------------|| Copyright (c) 2013, 2022, My Company Name| All rights reserved||-----------------------------------------------------------------------------*/

Rule 5.1.1.c

Synopsis:With respect to includes, each source file (.c and .h) shall be self-contained.Language:CLevel: 3Category:Conceptual Models

Description

Justification

Self-contained header files can be included in arbitrary order (without implicit dependencies). Aself-contained source file explicitly includes all header files from which typedefs, defines, functionprototypes etc. are used in the source. Each header file includes those other header files from which it usestypedefs, defines and function references. In this way self-contained source files can be compiled andchecked with SQ in isolation, thus before they are used by or integrated with other parts. Especially forinterface header files it holds that when the compiler or SQ determine (potential) problems they mostly canbe resolved easily before other code developed on basis of the content of these header files is written.

Example

CCBX_header.h header file content:

#include "header/ownbool.h" /* RIGHT: because of ownbool usage */int CCBX_fn(ownbool b);

and inclusion in .c source file:

title 05/21/22

5

Page 11: ASML C Coding Standard

#include "header/ownbool.h" /* RIGHT: because of usage of ownbool */#include "CCBX_header.h" /* RIGHT: because of usage CCBX_fn */...static int ccby_fn(void){ int e = OK; bool b1 = TRUE; /* #include "header/ownbool.h" needed */

e = CCBX_fn(b1); /* #include needed */ ..

Rule 5.1.1.d

Synopsis:Only files that are really needed shall be included.Language:CLevel: 8Category:Conceptual Models

Description

Justification

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

Rule 5.1.1.f

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

Language:CLevel: 8Category:Conceptual Models

Description

Justification

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

Example 1

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

Example 2

title 05/21/22

6

Page 12: ASML C Coding Standard

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

Rule 5.1.1.1.b

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

Language:CLevel: 2Category:Conceptual Models

Description

Justification

Since a header file may be used by source files and other header files, there is no way of knowing in whichsequence header files will be included, nor how many times any particular header will be included. Thismechanism 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 */

Rule 5.1.1.1.c

Synopsis:Naming convention of the include guard of an include file named CCBB_foo.h is of format:CCBB_FOO_H

Language:CLevel: 6Category:Conceptual Models

Description

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>

title 05/21/22

7

Page 13: ASML C Coding Standard

#endif /* CCBB_FOO_H */

Rule 5.1.1.2.b

Synopsis:Each non-trivial function shall be accompanied by a doxygen style function header.Language:CLevel: 6Category:Conceptual Models

Description

Justification

Enough information should be provided by the function header to help the reader to use the function withoutthe necessity of reading the implementation of the function and to help the reviewer to verify whether thefunction 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 {description} * \pre None * \post first_maintenance * maintenance_status * - Initialised with zeroes * \note The precondition implies that this is a maintenance object. */{ /* Function definition */}

Rule 5.1.2.b

Synopsis:Local variables shall not cause stack overflow.Language:CLevel: 3Category:Conceptual Models

title 05/21/22

8

Page 14: ASML C Coding Standard

Description

Justification

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

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

Rule 5.1.2.3.a

Synopsis:Side effects shall not be relied upon between successive sequence points.Language:CLevel: 3Category:Conceptual Models

Description

Justification

For a few constructs in C, the standard does not define the evaluation order when there is more than oneside-effect in it. Reliance on them can create problems which are very difficult to track down. Note that thiseven 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 (orneglectable) side effects can be used.

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

title 05/21/22

9

Page 15: ASML C Coding Standard

Rule 5.1.2.3.b

Synopsis:Expressions which mix operators from the set ">", ">=", ">", "^", "&", "|", "&&", "||" and whichuse two or more distinct operators from the latter set shall be fully parenthesized and shall notdepend on the C precedence rules.

Language:CLevel: 8Category:Conceptual Models

Description

Justification

Mixing relational and logical operators without explicitly adding parenthesis is a notorious source of error inC 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 ofoperands.

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 < j < k) /* WRONG */{ /* any statement */}

Example 4

if ((i > j) && (j > k)) /* RIGHT */{ /* any statement */}

Example 5

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

Example 6

title 05/21/22

10

Page 16: ASML C Coding Standard

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

Example 7

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

Example 8

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

Example 9

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

Example 10

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!

title 05/21/22

11

Page 17: ASML C Coding Standard

Environmental ConsiderationsRules

5.2.1.1.b Digraphs shall not be used: "<:", ":>", "<%", "%>", "%:".

Rule 5.2.1.1.b

Synopsis:Digraphs shall not be used: "<:", ":>", "<%", "%>", "%:".Language:CLevel: 2Category:Environmental Considerations

Description

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): "[", "]", "{", "}", "#", "##".

12

Page 18: ASML C Coding Standard

ConceptsRules

6.2.2.b Objects and functions with external linkage shall be declared in header files and defined afterincluding the header file that declares them.

6.2.2.c A variable declaration with storage class static shall have a scope limited to the source file.

6.2.3.a To avoid name collision, one shall not use the same name for different identifiers.

6.2.4.b Memory operations shall be symmetric; allocation and de-allocation shall take place in the samescope where the allocated variable is defined.

6.2.5.a One must not rely on the actual numerical value of an enum variable.

Rule 6.2.2.b

Synopsis:Objects and functions with external linkage shall be declared in header files and defined afterincluding the header file that declares them.

Language:CLevel: 6Category:Concepts

Description

Justification

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

Rule 6.2.2.c

Synopsis:A variable declaration with storage class static shall have a scope limited to the source file.Language:CLevel: 4Category:Concepts

Description

Justification

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

13

Page 19: ASML C Coding Standard

Rule 6.2.3.a

Synopsis:To avoid name collision, one shall not use the same name for different identifiers.Language:CLevel: 2Category:Concepts

Description

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;/* ... */{ float value; /* WRONG: obscures earlier 'value' */ /* ... */} /* ... */

Note

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

Rule 6.2.4.b

Synopsis:Memory operations shall be symmetric; allocation and de-allocation shall take place in the samescope where the allocated variable is defined.

Language:CLevel: 4Category:Concepts

Description

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 */

title 05/21/22

14

Page 20: ASML C Coding Standard

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 tothe caller. It must be clearly indicated in the interface documentation when de-allocation by the caller isrequired.

Rule 6.2.5.a

Synopsis:One must not rely on the actual numerical value of an enum variable.Language:CLevel: 6Category:Concepts

Description

Justification

The representation of enum types should not be relied upon, because this representation can change whenadding or removing items in the enum. One can iterate through an enum, but calculations with enum valuesare not allowed. The language doesn't make that difference, so it is left to the programmer to inspect themessages 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 */}

title 05/21/22

15

Page 21: ASML C Coding Standard

Example 2

typedef enum color_enum_tag{ COLOR_START = 0, RED, YELLOW, 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 */{}

title 05/21/22

16

Page 22: ASML C Coding Standard

ConversionsSeveral operators convert operand values from one type to another automatically. This subclause specifies theresult required from such an implicit conversion, as well as those that result from a cast operation (an explicitconversion).

Rules

6.3.a Unsafe implicit conversions in expressions, return statements, assignment statements or argumentlists shall not be used. Unsafe means: conversions where values are truncated and/or sign can belost.

6.3.b Unsafe implicit conversions of literals shall be avoided.

6.3.1.a Mixed signed/unsigned type arithmetic shall not be used.

6.3.2.1.a void expressions shall not be used in expressions.

6.3.2.2.a Pointer to and from integer conversions shall not be used. For instance on 64-bit x86 processorsthe size of an integer is 32-bits while the pointer is 64-bits. Therefore converting a pointer to aninteger will discard part of the address.

6.3.2.2.b For generic pointers void * shall be used rather than char *.

6.3.2.2.c Pointers shall not be converted to other pointer types.

6.3.2.2.d Pointers shall not be added, multiplied nor divided.

6.3.2.2.e Pointers shall not be subtracted from each other, unless their unqualified type is the same.

6.3.2.3.a bool shall be used as boolean type.

6.3.2.3.d Avoid conversions between booleans and non-boolean types

Rule 6.3.a

Synopsis:Unsafe implicit conversions in expressions, return statements, assignment statements or argumentlists shall not be used. Unsafe means: conversions where values are truncated and/or sign can belost.

Language:CLevel: 4Category:Conversions

Description

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 */

17

Page 23: ASML C Coding Standard

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]){ 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.

Rule 6.3.b

Synopsis:Unsafe implicit conversions of literals shall be avoided.Language:CLevel: 8Category:Conversions

Description

Justification

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

Example

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

title 05/21/22

18

Page 24: ASML C Coding Standard

}

Rule 6.3.1.a

Synopsis:Mixed signed/unsigned type arithmetic shall not be used.Language:CLevel: 2Category:Conversions

Description

Justification

In several cases with mixed signed/unsigned integral operands of binary operators, the signed operand will beconverted to an unsigned value. This can lead to unexpected changes of its value, resulting in unexpectedresults 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. */

Rule 6.3.2.1.a

Synopsis: void expressions shall not be used in expressions.Language:CLevel: 8Category:Conversions

title 05/21/22

19

Page 25: ASML C Coding Standard

Description

Justification

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

Example

void increment_counter(void);

i = increment_counter(); /* WRONG */

Note

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

Rule 6.3.2.2.a

Synopsis:Pointer to and from integer conversions shall not be used. For instance on 64-bit x86 processorsthe size of an integer is 32-bits while the pointer is 64-bits. Therefore converting a pointer to aninteger will discard part of the address.

Language:CLevel: 4Category:Conversions

Description

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;

title 05/21/22

20

Page 26: ASML C Coding Standard

char *p_address = (char*)p_base + offset; /* RIGHT */}

Rule 6.3.2.2.b

Synopsis:For generic pointers void * shall be used rather than char *.Language:CLevel: 6Category:Conversions

Description

Justification

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

Rule 6.3.2.2.c

Synopsis:Pointers shall not be converted to other pointer types.Language:CLevel: 6Category:Conversions

Description

Justification

Data structures have an alignment. Some structures must start on a 4 byte boundary, while for other structuresthe boundary is 2 or 1. When a misaligned structure is accessed this can cause an exception, but this differsper 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 amemory region) and a specific pointer (pointing to a piece of data stored in this memory region). Thereforeconversion 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 castbetween a "char" pointer and any other pointer.

Example 1

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

short *s; /* 2 byte alignment */

title 05/21/22

21

Page 27: ASML C Coding Standard

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

Example 2

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 notrepresent a legal int address. It would well be possible that an address exception would be generated onaccess of "i".

Rule 6.3.2.2.d

Synopsis:Pointers shall not be added, multiplied nor divided.Language:CLevel: 1Category:Conversions

Description

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

Rule 6.3.2.2.e

Synopsis:Pointers shall not be subtracted from each other, unless their unqualified type is the same.Language:CLevel: 2

title 05/21/22

22

Page 28: ASML C Coding Standard

Category:Conversions

Description

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 */

Rule 6.3.2.3.a

Synopsis:bool shall be used as boolean type.Language:CLevel: 5Category:Conversions

Description

Justification

Different types of booleans should not be mixed (bool, Boolean, _Bool, int and embedded C-languageboolean expression) because they have different definitions and therefore different behavior.

Example

#define TRUE 1int b = TRUE; /* WRONG */bool my_bool = true; /* RIGHT */

Justification

title 05/21/22

23

Page 29: ASML C Coding Standard

If a variable is passed to an X Motif library function it should be declared as being of type Boolean instead ofbool. This is because the X Motif library function expect this Boolean type, which has a subtle differentsemantics compared to bool.

Rule 6.3.2.3.d

Synopsis:Avoid conversions between booleans and non-boolean typesLanguage:CLevel: 6Category:Conversions

Description

Justification

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

Example

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 */

title 05/21/22

24

Page 30: ASML C Coding Standard

Lexical ElementsRules

6.4.b The tab character (0x09 ASCII) shall not be used.

6.4.1.a C keywords are reserved for use as keywords and shall not be used otherwise.

6.4.1.b Only with a very good reason, the asm keyword may be used to insert assembly language directlyinto the translator output.

6.4.1.1.a Do not use C++ keywords.

6.4.1.1.b Do not use C++ alternative representations that are not part of the C keywords (see also 6.4.1.a).

6.4.2.a Identifiers shall satisfy the standard C syntax for identifiers.

6.4.2.b Identifiers shall not be defined with one or more leading underscores (_).

6.4.2.d Don't use extern variable declarations in header files, except for consts.

6.4.4.b Use suffix 'L' instead of 'l' to avoid confusion

6.4.4.1.a Only decimal or hexadecimal notation may be used for integer constants.

6.4.4.1.b Use clear constant values. Small letters shall not be used, expecially to avoid confusion between l(letter l) and 1 (digit one). The letter U shall be written in uppercase to be consistent with the caseof the letter L.

6.4.4.3.a Only the first entry in an enumerator shall be explicitly defined using '='.

6.4.4.4.a Only ANSI defined escape sequences shall be used.

6.4.5.a A character string literal token shall not be adjacent to a wide string literal token.

6.4.9.a Comments in the form of opening (/*) and closing (*/) shall not be nested.

6.4.9.c Do not use mixed comments.

Rule 6.4.b

Synopsis:The tab character (0x09 ASCII) shall not be used.Language:CLevel: 8Category:Lexical Elements

Description

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 adifferent layout per editor. Manual merging with a garbled layout will lead to merge errors, review errors, etc.

25

Page 31: ASML C Coding Standard

Rule 6.4.1.a

Synopsis:C keywords are reserved for use as keywords and shall not be used otherwise.Language:CLevel: 2Category:Lexical Elements

Description

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 registerrestrict return short signed

sizeof static struct switch typedefunion

unsigned void volatile while _Bool _Complex

_Imaginary

Rule 6.4.1.b

Synopsis:Only with a very good reason, the asm keyword may be used to insert assembly language directlyinto the translator output.

Language:CLevel: 2Category:Lexical Elements

Description

Justification

Because of the variety of the used syntaxes (by different compilers) the asm keyword is not portable. It isbetter to use assembly source files with a c-header.

Example 1

asm("TOIEEE ARO,R0"); /* RIGHT */

Example 2

title 05/21/22

26

Page 32: ASML C Coding Standard

asm("...." : "..."); /* RIGHT */

Example 3

asm volatile("...." : "..."); /* RIGHT */

Example 4

__asm__ ("..." : "...."); /* WRONG */

Example 5

__asm__ __volatile__ ("...." : "...."); /* WRONG */

Rule 6.4.1.1.a

Synopsis:Do not use C++ keywords.Language:CLevel: 6Category:Lexical Elements

Description

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_castdecltype delete

dynamic_castexplicit export false

friend mutable namespacenew

noexcept nullptr operator private

protected public public reinterpret_cast

static_assert static_casttemplate this

thread_local throw true try

typeid typenameusing virtual

wchar_t

title 05/21/22

27

Page 33: ASML C Coding Standard

Rule 6.4.1.1.b

Synopsis:Do not use C++ alternative representations that are not part of the C keywords (see also 6.4.1.a).Language:CLevel: 4Category:Lexical Elements

Description

Justification

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

Example

int bitand; /* WRONG */

Note

C++ alternative representations are:

and and_eqbitand bitor

compl not not_eqor

or_eq xor xor_eq

Rule 6.4.2.a

Synopsis: Identifiers shall satisfy the standard C syntax for identifiers.Language:CLevel: 2Category:Lexical Elements

Description

Justification

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

Example

int a$b; /* WRONG */

title 05/21/22

28

Page 34: ASML C Coding Standard

Rule 6.4.2.b

Synopsis: Identifiers shall not be defined with one or more leading underscores (_).Language:CLevel: 5Category:Lexical Elements

Description

Justification

Leading underscores are reserved for compiler writers.

Example

int _tmpval; /* WRONG */#define _TEMPCONST (19) /* WRONG */

Rule 6.4.2.d

Synopsis:Don't use extern variable declarations in header files, except for consts.Language:CLevel: 6Category:Lexical Elements

Description

Justification

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

Example

In header files:

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

title 05/21/22

29

Page 35: ASML C Coding Standard

Rule 6.4.4.b

Synopsis:Use suffix 'L' instead of 'l' to avoid confusionLanguage:CLevel: 8Category:Lexical Elements

Description

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 */

Rule 6.4.4.1.a

Synopsis:Only decimal or hexadecimal notation may be used for integer constants.Language:CLevel: 6Category:Lexical Elements

Description

Justification

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

Example

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

Rule 6.4.4.1.b

Synopsis:Use clear constant values. Small letters shall not be used, expecially to avoid confusion between l(letter l) and 1 (digit one). The letter U shall be written in uppercase to be consistent with the caseof the letter L.

Language:CLevel: 8Category:Lexical Elements

title 05/21/22

30

Page 36: ASML C Coding Standard

Description

Justification

Readability.

Example

#define CCBB_FIRST_DATE 19960101UL /* RIGHT */#define CCBB_LAST_DATE 20960101ul /* WRONG */

Rule 6.4.4.3.a

Synopsis:Only the first entry in an enumerator shall be explicitly defined using '='.Language:CLevel: 8Category:Lexical Elements

Description

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;

Rule 6.4.4.4.a

Synopsis:Only ANSI defined escape sequences shall be used.Language:CLevel: 2Category:Lexical Elements

Description

Justification

title 05/21/22

31

Page 37: ASML C Coding Standard

Escape sequences (those beginning with \) other than those defined by the ANSI standard have undefinedbehavior, 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 */

Rule 6.4.5.a

Synopsis:A character string literal token shall not be adjacent to a wide string literal token.Language:CLevel: 2Category:Lexical Elements

Description

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 */

Rule 6.4.9.a

Synopsis:Comments in the form of opening (/*) and closing (*/) shall not be nested.Language:CLevel: 2Category:Lexical Elements

Description

Justification

title 05/21/22

32

Page 38: 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 ascomments.

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 thatalready exist for source code exclusion shall be used.

Rule 6.4.9.c

Synopsis:Do not use mixed comments.Language:CLevel: 8Category:Lexical Elements

Description

Justification

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

Example

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

title 05/21/22

33

Page 39: ASML C Coding Standard

ExpressionsAn expression is a sequence of operators and operands that specifies computation of a value, or thatdesignates an object or a function, or that generates side effects, or that performs a combination thereof. Thevalue computations of the operands of an operator are sequenced before the value computation of the resultof the operator.

Rules

6.5.a Bitwise operations shall only be applied on operands of unsigned type.

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

6.5.2.1.b typedef for an array of unknown size shall not be used.

6.5.2.2.b Do not declare functions within functions.

6.5.2.2.c Do not use functions marked as deprecated.

6.5.2.3.a When structures are accessed by means of a pointer, the pointer-to notation -> rather than themember notation * shall be used to denote a specified member of the structure.

6.5.2.3.b Structs or unions must be passed by reference into functions with variable numbers of parameters.

6.5.2.3.d Do not use nested structures.

6.5.3.1.a Do not mix postfix and prefix increment and/or decrement in a statement.

6.5.3.1.b Don't increment (decrement) a pointer to a function.

6.5.3.2.a A variable declared as an array shall not be used as a pointer.

6.5.3.3.a The unary plus operator shall not be used.

6.5.3.3.b Unary minus shall only be applied to an operand having a signed arithmetic type.

6.5.3.4.a sizeof shall not be applied to an expression with side-effects.

6.5.3.4.b Don't use sizeof on a variable of an array type that is passed as argument.

6.5.3.4.c Don't apply sizeof to a function.

6.5.4.a Casting shall only be used to denote required casting.

6.5.7.b The right operand of a left shift operator for a signed type as left operand shall not be so large thatthe resulting value cannot be represented.

6.5.8.a Comparison of unsigned operands shall not occur against negative values.

6.5.8.c Don't compare floats of different types.

6.5.8.d Comparison of floating point numbers (float or double) shall preferably be avoided.

6.5.8.e Use memcmp only to compare arrays of scalar types.

6.5.8.f Do not compare floating point numbers with memcmp.

6.5.9.a Pointer comparison shall only be done for compatible pointer types.

6.5.9.b Floating point expressions shall not be compared using the "==", "!=" operators. Floating pointexpressions shall be compared using special functions.

6.5.13.a The right-hand operand of the "&&" or "||" operator shall not contain any side-effects.

6.5.15.a The second and third operand of a conditional expression of the conditional operator shall notcontain side-effects.

6.5.16.a Do not use nested assignments.

6.5.16.b Do not discard const qualifiers in pointer assignments.

6.5.17.a The comma operator shall not be used.

34

Page 40: ASML C Coding Standard

Rule 6.5.a

Synopsis:Bitwise operations shall only be applied on operands of unsigned type.Language:CLevel: 4Category:Expressions

Description

Justification

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

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 signedtype and a non-negative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 hasa signed type and a negative value, the resulting value is implementation defined.

Rule 6.5.2.1.a

Synopsis:Array subscripting requires a pointer to object type and one or more integral subscript expressions.The indices must be within the bounds values of the (allocated) array.

Language:CLevel: 1Category:Expressions

Description

Justification

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

Example

int i;int a[6];

for (i = 0; i <= 6; i++){ a[i] = 0; /* WRONG: Index gets a value greater than the number of elements. */}

title 05/21/22

35

Page 41: ASML C Coding Standard

Rule 6.5.2.1.b

Synopsis: typedef for an array of unknown size shall not be used.Language:CLevel: 1Category:Expressions

Description

Justification

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

Example

typedef int array[];

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

Rule 6.5.2.2.b

Synopsis:Do not declare functions within functions.Language:CLevel: 3Category:Expressions

Description

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 */ { ... }};

title 05/21/22

36

Page 42: ASML C Coding Standard

Rule 6.5.2.2.c

Synopsis:Do not use functions marked as deprecated.Language:CLevel: 6Category:Expressions

Description

Justification

Adding new uses of deprecated functions or macros makes it harder to get rid of these legacy functions ormacros. 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 componentowner. This configuration is customizable per release. Please contact the owner of the functional element foradvice when this rule yields a violation in your code.

Rule 6.5.2.3.a

Synopsis:When structures are accessed by means of a pointer, the pointer-to notation -> rather than themember notation * shall be used to denote a specified member of the structure.

Language:CLevel: 8Category:Expressions

Description

Justification

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

Example

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

title 05/21/22

37

Page 43: ASML C Coding Standard

Rule 6.5.2.3.b

Synopsis:Structs or unions must be passed by reference into functions with variable numbers of parameters.Language:CLevel: 5Category:Expressions

Description

Justification

The C standard requires that the type of function arguments matches the type of the parameters the functionexpects. 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 ofprogramming 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 tofunctions 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 */}

Rule 6.5.2.3.d

Synopsis:Do not use nested structures.Language:CLevel: 6Category:Expressions

Description

Justification

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

Example

title 05/21/22

38

Page 44: ASML C Coding Standard

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 */

Rule 6.5.3.1.a

Synopsis:Do not mix postfix and prefix increment and/or decrement in a statement.Language:CLevel: 3Category:Expressions

Description

Justification

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

Example

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

Rule 6.5.3.1.b

Synopsis:Don't increment (decrement) a pointer to a function.Language:CLevel: 2Category:Expressions

Description

The increment and decrement operators are not valid for pointers to functions. See the StackOverflowreference for more details. For instance:

function_ptr++; /* WRONG */

title 05/21/22

39

Page 45: ASML C Coding Standard

Rule 6.5.3.2.a

Synopsis:A variable declared as an array shall not be used as a pointer.Language:CLevel: 6Category:Expressions

Description

Justification

An array name acts as a pointer to the first element of the array. However, using it that way can be a sourceof 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, theprogrammer's intention is clear.

Example 3

{ int a[10]; int *a_p;

*a = 1; /* WRONG */

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

title 05/21/22

40

Page 46: ASML C Coding Standard

Rule 6.5.3.3.a

Synopsis:The unary plus operator shall not be used.Language:CLevel: 6Category:Expressions

Description

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? */

Rule 6.5.3.3.b

Synopsis:Unary minus shall only be applied to an operand having a signed arithmetic type.Language:CLevel: 1Category:Expressions

Description

Justification

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

Example

long j;unsigned int i = 1;signed int k = 1;...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.

title 05/21/22

41

Page 47: ASML C Coding Standard

Rule 6.5.3.4.a

Synopsis: sizeof shall not be applied to an expression with side-effects.Language:CLevel: 3Category:Expressions

Description

Justification

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

Example

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

Rule 6.5.3.4.b

Synopsis:Don't use sizeof on a variable of an array type that is passed as argument.Language:CLevel: 2Category:Expressions

Description

Justification

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

Example

void m1(char a[100]) { int x = sizeof(a); /* WRONG, x == 4 or x == 8 */}

void m2(void) { char a[100] = { 0 }; int x = sizeof(a); /* RIGHT, x == 100 */}

title 05/21/22

42

Page 48: ASML C Coding Standard

Rule 6.5.3.4.c

Synopsis:Don't apply sizeof to a function.Language:CLevel: 2Category:Expressions

Description

The sizeof operator is not defined for functions:

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

Rule 6.5.4.a

Synopsis:Casting shall only be used to denote required casting.Language:CLevel: 8Category:Expressions

Description

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 */

Rule 6.5.7.b

Synopsis:The right operand of a left shift operator for a signed type as left operand shall not be so large thatthe resulting value cannot be represented.

Language:CLevel: 4Category:Expressions

Description

Justification

title 05/21/22

43

Page 49: 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 */

Rule 6.5.8.a

Synopsis:Comparison of unsigned operands shall not occur against negative values.Language:CLevel: 6Category:Expressions

Description

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 */{ ...}

Rule 6.5.8.c

Synopsis:Don't compare floats of different types.Language:CLevel: 6Category:Expressions

Description

Justification

Difference in precision may result in unexpected result.

title 05/21/22

44

Page 50: 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 typewill make the numbers comparable (at the cost of information loss).

Rule 6.5.8.d

Synopsis:Comparison of floating point numbers (float or double) shall preferably be avoided.Language:CLevel: 8Category:Expressions

Description

Justification

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

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 */

Rule 6.5.8.e

Synopsis:Use memcmp only to compare arrays of scalar types.Language:CLevel: 2Category:Expressions

Description

title 05/21/22

45

Page 51: ASML C Coding Standard

Justification

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

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 */}

Rule 6.5.8.f

Synopsis:Do not compare floating point numbers with memcmp.Language:CLevel: 8Category:Expressions

Description

Justification

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

Example

double a = NAN;double b = NAN;

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

title 05/21/22

46

Page 52: ASML C Coding Standard

{ /* 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 */}

Rule 6.5.9.a

Synopsis:Pointer comparison shall only be done for compatible pointer types.Language:CLevel: 2Category:Expressions

Description

Justification

Language constraint.

Rule 6.5.9.b

Synopsis:Floating point expressions shall not be compared using the "==", "!=" operators. Floating pointexpressions shall be compared using special functions.

Language:CLevel: 3Category:Expressions

Description

Justification

title 05/21/22

47

Page 53: ASML C Coding Standard

Comparing floating point expressions for equality or inequality is a notorious and well-documented source ofsoftware 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

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 agood intention, but still the code can be criticized. If you divide by a very small number, an overflow canoccur. The same can be said about testing for NAN.

title 05/21/22

48

Page 54: ASML C Coding Standard

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 somedoubt if the new values are still within a reasonable range, a new range test can be made. If this way ofprogramming is well thought through, then it is not necessary to test on 0.0 before every division. Like inprogramming 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 codingpractice because the value has a second meaning in such case. First, it says if something has been initializedand second, it contains the result of a measurement (that value should never be 0.0!). This problem is difficultto remove in old code.

Rule 6.5.13.a

Synopsis:The right-hand operand of the "&&" or "||" operator shall not contain any side-effects.Language:CLevel: 6Category:Expressions

Description

Justification

The right-hand operand of a "&&" or "||" is conditionally executed. Besides, the precedence of operators in Cis 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 */}

Rule 6.5.15.a

Synopsis:The second and third operand of a conditional expression of the conditional operator shall notcontain side-effects.

Language:C

title 05/21/22

49

Page 55: ASML C Coding Standard

Level: 6Category:Expressions

Description

Justification

Example 1

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

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 */}

Rule 6.5.16.a

Synopsis:Do not use nested assignments.Language:CLevel: 8Category:Expressions

Description

Justification

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

Example

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

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

title 05/21/22

50

Page 56: ASML C Coding Standard

z = 0;

Rule 6.5.16.b

Synopsis:Do not discard const qualifiers in pointer assignments.Language:CLevel: 6Category:Expressions

Description

Justification

Discarding const qualifiers in pointer assignments is allowed in C but not in C++. In order to keep code beingportable 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 */

Rule 6.5.17.a

Synopsis:The comma operator shall not be used.Language:CLevel: 6Category:Expressions

Description

Justification

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

Example

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

title 05/21/22

51

Page 57: ASML C Coding Standard

DeclarationsRules

6.7.a Only one identifier type shall be declared on each source line.

6.7.1.a Identifiers with file scope shall be declared static, thus preventing them from having global scope.

6.7.1.b Since auto is redundant it shall be omitted to avoid cluttering up declarations.

6.7.1.c Since "register" is redundant it shall be omitted to avoid cluttering up declarations.

6.7.2.a Compiler-specific extensions shall not be used in type specifiers.

6.7.2.b Every identifier declaration shall include a type specifier.

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

6.7.2.2.a Mixing of different enum types is not allowed.

6.7.3.a "const" shall be used to specify that a variable is non-modifiable.

6.7.5.a Only variables and parameters that are used shall be declared.

6.7.5.2.a Array bounds shall be specified as integral constant expressions.

6.7.5.3.a All function prototypes shall specify the type and the name of each of their parameters.

6.7.5.3.b A function shall only be used if its prototype is known.

6.7.5.3.c Avoid unused static functions

6.7.8.a All variables shall be initialized or assigned before being read.

6.7.8.b The initializer for a struct, union or array shall be enclosed in braces.

6.7.8.c For a struct the initializer should be {0} or all fields should be initialized.

6.7.8.d All variables containing a pointer shall be initialized.

Rule 6.7.a

Synopsis:Only one identifier type shall be declared on each source line.Language:CLevel: 8Category:Declarations

Description

Justification

Using one declaration on a line the code will become more readable and in the case of pointer declarationsnot result in unexpected behavior. Besides, to be able to determine the amount of software, a uniform way ofdeclaring 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 */

52

Page 58: ASML C Coding Standard

Rule 6.7.1.a

Synopsis: Identifiers with file scope shall be declared static, thus preventing them from having global scope.Language:CLevel: 4Category:Declarations

Description

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 */

int ccbb_public; /* external scope */

static int ccbb_private; /* file scope */

Rule 6.7.1.b

Synopsis:Since auto is redundant it shall be omitted to avoid cluttering up declarations.Language:CLevel: 5Category:Declarations

Description

Justification

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

Rule 6.7.1.c

Synopsis:Since "register" is redundant it shall be omitted to avoid cluttering up declarations.Language:CLevel: 4Category:Declarations

title 05/21/22

53

Page 59: ASML C Coding Standard

Description

Justification

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

Rule 6.7.2.a

Synopsis:Compiler-specific extensions shall not be used in type specifiers.Language:CLevel: 2Category:Declarations

Description

Justification

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

Example

long long doublelong; /* WRONG */

Note

"long long" is a portable C99 type.

Rule 6.7.2.b

Synopsis:Every identifier declaration shall include a type specifier.Language:CLevel: 6Category:Declarations

Description

Justification

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

title 05/21/22

54

Page 60: ASML C Coding Standard

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 */{}

Rule 6.7.2.1.a

Synopsis:Do not use bit-fields for combining multiple logical values in one memory location.Language:CLevel: 4Category:Declarations

Description

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.

Rule 6.7.2.2.a

Synopsis:Mixing of different enum types is not allowed.Language:CLevel: 4Category:Declarations

Description

Justification

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

title 05/21/22

55

Page 61: ASML C Coding Standard

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 assignenumerators from one enum type to another enum type will cause a C++ compiler error.

Rule 6.7.3.a

Synopsis: "const" shall be used to specify that a variable is non-modifiable.Language:CLevel: 5Category:Declarations

Description

Justification

It is a good programming practice to specify at declaration and definition of variables or parameters that theirvalues will not be changed or, in case of a pointer, that their reference will not be changed.

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;}

Rule 6.7.5.a

Synopsis:Only variables and parameters that are used shall be declared.Language:C

title 05/21/22

56

Page 62: ASML C Coding Standard

Level: 4Category:Declarations

Description

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 thiscomment in front of a declaration: /*@unused@*/. Using the aforementioned comment with a variable that isused 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 */{ return status;}

Rule 6.7.5.2.a

Synopsis:Array bounds shall be specified as integral constant expressions.Language:CLevel: 5Category:Declarations

Description

Justification

Constant expressions enable tooling to check if indexing is in the defined array range. Also, compile timeundefined 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.*/

title 05/21/22

57

Page 63: ASML C Coding Standard

...}

Note

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

Rule 6.7.5.3.a

Synopsis:All function prototypes shall specify the type and the name of each of their parameters.Language:CLevel: 2Category:Declarations

Description

Justification

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

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 */{}

Rule 6.7.5.3.b

Synopsis:A function shall only be used if its prototype is known.Language:CLevel: 2Category:Declarations

Description

Justification

title 05/21/22

58

Page 64: ASML C Coding Standard

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

Rule 6.7.5.3.c

Synopsis:Avoid unused static functionsLanguage:CLevel: 8Category:Declarations

Description

Static functions have file scope. If they are not called somewherein the same file as they are defined, thenthey are dead and can be removed.

Example:

// file doesn't contain any call to getstatusstatic int getstatus(int index) {}

Rule 6.7.8.a

Synopsis:All variables shall be initialized or assigned before being read.Language:CLevel: 8Category:Declarations

Description

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 */}

title 05/21/22

59

Page 65: ASML C Coding Standard

Rule 6.7.8.b

Synopsis:The initializer for a struct, union or array shall be enclosed in braces.Language:CLevel: 4Category:Declarations

Description

Justification

Readability.

Example 1

typedef struct xy{ int x; int y;

} xyvect;

xyvect origin = 0; /* WRONG */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 memoryit is referring to.

title 05/21/22

60

Page 66: ASML C Coding Standard

Rule 6.7.8.c

Synopsis:For a struct the initializer should be {0} or all fields should be initialized.Language:CLevel: 4Category:Declarations

Description

Justification

Readability.

Example 1

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 */

Rule 6.7.8.d

Synopsis:All variables containing a pointer shall be initialized.Language:CLevel: 6Category:Declarations

title 05/21/22

61

Page 67: ASML C Coding Standard

Description

Justification

In this way uninitialized memory is banned out.

Example

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 */

title 05/21/22

62

Page 68: ASML C Coding Standard

Statement and BlocksA statement specifies an action to be performed. Except as indicated, statements are executed in sequence. Ablock allows a set of declarations and statements to be grouped into one syntactic unit.

Rules

6.8.a All control statements shall be fully brace enclosed. This means that all "if", "while", "for", "do"and "switch" statements are followed by a brace-enclosed compound statement.

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

6.8.d Avoid magic numbers.

6.8.1.a Statements shall not be labelled except for "case" and "default" in a switch-statement.

6.8.3.a Each expression and statement shall have an effect.

6.8.3.b A null statement (;) shall not be used.

6.8.4.b The condition (or guard) of a selective alternative shall be a logical operator, an equality operatoror a relational expression (and not be an assignment). Exception is made for boolean type. Forboolean type no relational expression is required.

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

6.8.4.1.b N-ary selection constructs programmed using "if ... else if ..." shall have an "else" clause.

6.8.4.2.a The switch expression shall not contain any logical expression (one or more of the ">", ">=", "

6.8.4.2.b "switch" statements shall have one and only one "default" clause.

6.8.4.2.c Each non empty case clause and default clause shall end with a break statement.

6.8.4.2.d The default clause shall be the last entry in the switch statement.

6.8.4.2.e Make sure all code in a switch statement serves a purpose.

6.8.5.a The termination condition of iteration shall not have a constant value.

6.8.5.1.a The variables used in expression 2 of a "for" loop shall not be changed in the loop body andexpression 3 at the same time.

6.8.5.1.c The loop variable of a for loop shall be used in the loop body.

6.8.6.1.a The "goto" statement shall not be used.

6.8.6.2.a The "continue" statement shall not be used.

6.8.6.3.a The break statement shall not be used to exit from an iteration statement ("for" or "while").

6.8.6.4.a There shall be exactly one "return" statement in a function returning non-void.

6.8.6.4.b There shall be no return statement in a void function.

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

6.8.6.4.d Function return values that are error codes shall not be ignored.

Rule 6.8.a

Synopsis:All control statements shall be fully brace enclosed. This means that all "if", "while", "for", "do"and "switch" statements are followed by a brace-enclosed compound statement.

Language:CLevel: 5Category:Statement and Blocks

63

Page 69: ASML C Coding Standard

Description

Justification

By using braces a visible grouping of statements is created. Programming errors can be caused when the bodyof 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{ ...}

Rule 6.8.c

Synopsis:Any statement that is logically never executed shall not occur in the source code.Language:CLevel: 3Category:Statement and Blocks

Description

Justification

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

title 05/21/22

64

Page 70: ASML C Coding Standard

Rule 6.8.d

Synopsis:Avoid magic numbers.Language:CLevel: 8Category:Statement and Blocks

Description

Justification

Do not use hard-coded numbers. It is better practice to use a macro constant or a typed constant (e.g. "constfloat"); 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.50137const 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

/* 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++;}

Rule 6.8.1.a

Synopsis:Statements shall not be labelled except for "case" and "default" in a switch-statement.Language:C

title 05/21/22

65

Page 71: ASML C Coding Standard

Level: 3Category:Statement and Blocks

Description

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 */

Rule 6.8.3.a

Synopsis:Each expression and statement shall have an effect.Language:CLevel: 6Category:Statement and Blocks

Description

Justification

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

Example

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

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

Rule 6.8.3.b

Synopsis:A null statement (;) shall not be used.Language:CLevel: 6Category:Statement and Blocks

title 05/21/22

66

Page 72: ASML C Coding Standard

Description

Justification

Empty statements are probably a bug (forgetting parentheses when calling a function?). Since all selectionand iteration statements should have a compound statement as the body, a null body should have a commentsuitably indented.

The other use for a null statement is to carry a label before a closing brace, but since labels are prohibited bythis standard so such null statements are, by implication, also prohibited.

Example

if (i == 0); /* WRONG */if (i == 0){ ; /* WRONG */}

if (i == 0) /* RIGHT */{ /* suitable comment */}

Rule 6.8.4.b

Synopsis:The condition (or guard) of a selective alternative shall be a logical operator, an equality operatoror a relational expression (and not be an assignment). Exception is made for boolean type. Forboolean type no relational expression is required.

Language:CLevel: 6Category:Statement and Blocks

Description

Justification

Example 1

if (i = a) /* WRONG: assignment as well as a test */{ /* Any statement */}

Example 2

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

title 05/21/22

67

Page 73: ASML C Coding Standard

Example 3

if (i == 1) /* RIGHT: equality operator */{ /* Any statement */}

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 */}

Rule 6.8.4.c

Synopsis:The termination condition of iterations shall be of type boolean.Language:CLevel: 7Category:Statement and Blocks

title 05/21/22

68

Page 74: ASML C Coding Standard

Description

Justification

Conditions are meant to test boolean values, not integers, characters, pointers or other types. In the lattercases, 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 */

Rule 6.8.4.1.b

Synopsis:N-ary selection constructs programmed using "if ... else if ..." shall have an "else" clause.Language:CLevel: 6Category:Statement and Blocks

Description

Justification

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

Example 1

if (temp < 0){

title 05/21/22

69

Page 75: ASML C Coding Standard

/* 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.

Rule 6.8.4.2.a

Synopsis:The switch expression shall not contain any logical expression (one or more of the ">", ">=", "Language:CLevel: 5Category:Statement and Blocks

Description

Justification

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

Example

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

title 05/21/22

70

Page 76: ASML C Coding Standard

Rule 6.8.4.2.b

Synopsis: "switch" statements shall have one and only one "default" clause.Language:CLevel: 2Category:Statement and Blocks

Description

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 possiblespecial 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 notrequired.

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

#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:

title 05/21/22

71

Page 77: ASML C Coding Standard

break;} /* RIGHT: no default clause required because all enum values are covered. */

Rule 6.8.4.2.c

Synopsis:Each non empty case clause and default clause shall end with a break statement.Language:CLevel: 2Category:Statement and Blocks

Description

Justification

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

Example 1

switch (trigger){case 1:case 2: /* do something */ break; /* RIGHT */default: /* WRONG */}

Example 2

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

Rule 6.8.4.2.d

Synopsis:The default clause shall be the last entry in the switch statement.Language:CLevel: 5Category:Statement and Blocks

Description

title 05/21/22

72

Page 78: ASML C Coding Standard

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 */ /* any statement */ break;default: /* any statement */ break;}

Rule 6.8.4.2.e

Synopsis:Make sure all code in a switch statement serves a purpose.Language:CLevel: 6Category:Statement and Blocks

Description

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: { /* ... */

title 05/21/22

73

Page 79: ASML C Coding Standard

}}

Example 2

switch (i) /* A Switch with only one case. Better use if */{case 1: /* any statement */ break;default: { /* ... */ }}

Rule 6.8.5.a

Synopsis:The termination condition of iteration shall not have a constant value.Language:CLevel: 4Category:Statement and Blocks

Description

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 */}

title 05/21/22

74

Page 80: ASML C Coding Standard

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.

Rule 6.8.5.1.a

Synopsis:The variables used in expression 2 of a "for" loop shall not be changed in the loop body andexpression 3 at the same time.

Language:CLevel: 6Category:Statement and Blocks

Description

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 */}

Rule 6.8.5.1.c

Synopsis:The loop variable of a for loop shall be used in the loop body.Language:CLevel: 5Category:Statement and Blocks

title 05/21/22

75

Page 81: ASML C Coding Standard

Description

Justification

In most cases not using the loop variable will be unintentional.

Rule 6.8.6.1.a

Synopsis:The "goto" statement shall not be used.Language:CLevel: 6Category:Statement and Blocks

Description

Justification

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

Example

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

Rule 6.8.6.2.a

Synopsis:The "continue" statement shall not be used.Language:CLevel: 6Category:Statement and Blocks

Description

Justification

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

Example 1

for (i = 0; i < n; i++){ if (a[i] < 0)

title 05/21/22

76

Page 82: ASML C Coding Standard

{ /* process negative term */ continue; /* WRONG */ } /* Process positive term */}

Example 2

for (i = 0; i < n; i++){ if (a[i] < 0) { /* Process negative term */ } else /* a[i] >= 0 */ /* RIGHT */ { /* Process positive term */ } }

Rule 6.8.6.3.a

Synopsis:The break statement shall not be used to exit from an iteration statement ("for" or "while").Language:CLevel: 6Category:Statement and Blocks

Description

Justification

"break" statements cause breaks in the normal structured control flow of a program. For this reason they shallbe avoided (apart from use in switch statements) as they affect the readability and maintainability of the code.

Example 1

for (i = 0; i < n; i++){ if (c[i] == ' ') { break; /* WRONG */ }}

Example 2

while (c[0] == ' '){ ...c... break; /* WRONG */}

Example 3

i = 0;

title 05/21/22

77

Page 83: ASML C Coding Standard

while ((i < n) && (c[i] != ' ')) /* RIGHT */{ i++;}/* status: i == n || ((0 <= i < n) && (c[i] == ' ')) */

Rule 6.8.6.4.a

Synopsis:There shall be exactly one "return" statement in a function returning non-void.Language:CLevel: 9Category:Statement and Blocks

Description

Justification

More than one exit point indicates a forced break in control flow and, like any break in control flow, leads tocode 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;}

return result; /* RIGHT */

Exception

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

Note

title 05/21/22

78

Page 84: ASML C Coding Standard

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.

Rule 6.8.6.4.b

Synopsis:There shall be no return statement in a void function.Language:CLevel: 9Category:Statement and Blocks

Description

Justification

There is no need for a return statement in a void function. Absence of a return statement prevents adding anexpression 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 */}

Rule 6.8.6.4.c

Synopsis:A function "return" expression shall be compatible with its explicitly defined type.Language:CLevel: 2Category:Statement and Blocks

Description

Justification

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

Example 1

title 05/21/22

79

Page 85: ASML C Coding Standard

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

Example 2

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

Rule 6.8.6.4.d

Synopsis:Function return values that are error codes shall not be ignored.Language:CLevel: 6Category:Statement and Blocks

Description

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){ 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 */ { ... }}

title 05/21/22

80

Page 86: ASML C Coding Standard

External DefinitionsRules

6.9.1.a Function pointer parameters should not be declared as ordinary pointer type. A type should be usedwhich is declared by a "typedef" declaration.

6.9.1.b Do not use K&R declaration style.

6.9.2.a Explicitly use "static" or "extern" on all global const declarations.

6.9.2.b Only static global variables that are used shall be declared.

Rule 6.9.1.a

Synopsis:Function pointer parameters should not be declared as ordinary pointer type. A type should beused which is declared by a "typedef" declaration.

Language:CLevel: 6Category:External Definitions

Description

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);

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

81

Page 87: ASML C Coding Standard

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

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

Rule 6.9.1.b

Synopsis:Do not use K&R declaration style.Language:CLevel: 6Category:External Definitions

Description

Justification

K&R declaration style is not supported in C++. So programs will not be portable from C to C++ if they usethis 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;}

Rule 6.9.2.a

Synopsis:Explicitly use "static" or "extern" on all global const declarations.Language:CLevel: 6Category:External Definitions

Description

Justification

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

title 05/21/22

82

Page 88: ASML C Coding Standard

Rule 6.9.2.b

Synopsis:Only static global variables that are used shall be declared.Language:CLevel: 8Category:External Definitions

Description

Justification

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

title 05/21/22

83

Page 89: ASML C Coding Standard

Preprocessing DirectivesRules

6.10.a Use of pre-processor directives shall be according to strict ANSI syntax and constraints.

6.10.b Only perform token pasting with the token pasting operator (##).

6.10.1.a Code checker flags shall not be used in the source code.

6.10.1.c #ifdef, #ifndef, #if defined and #if !defined are not allowed in external header files.

6.10.1.e Don't use "#if 0" as comments

6.10.2.a All headers files shall be identified by an #include directive.

6.10.2.b Including source files is not allowed.

6.10.2.c It is forbidden to include hpp files in C files.

6.10.3.a Use of macros shall strictly be according to the ANSI C89 macro syntax and within the ANSIC89 macro constraints.

6.10.3.b #define macros shall only be used for symbolic constants. They shall not be used for functionlike macros if a function can be written to accomplish the same task.

6.10.3.c Any instance of macro parameters, macro body and macro operations shall be enclosed withinparenthesis.

6.10.3.d Macros should not end with a semicolon.

6.10.3.e Use a semicolon at the end of a function-like macro call.

6.10.3.2.b A macro shall not comprise both the "#" and "##" operators simultaneously.

6.10.3.3.a Result of "##" operator shall be a legal pre-processing token.

6.10.3.4.a Recursive macro definitions shall not be used.

6.10.3.5.a Macros shall only be #define'd and #undef'ed at file scope.

6.10.4.a The line splicing character ('\' at the end of a line) shall not be used, except in preprocessormacros.

6.10.4.b When used, the line-splicing character ('\' at the end of a line) shall immediately be followed bythe newline character.

6.10.4.c Do not use mixed EOL characters in a file.

6.10.6.a The pragma directive and pragma operator shall not be used.

6.10.8.b Only the predefined macro names __FILE__, __LINE__ and __func__ may be used.

Rule 6.10.a

Synopsis:Use of pre-processor directives shall be according to strict ANSI syntax and constraints.Language:CLevel: 2Category:Preprocessing Directives

Description

Justification

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

84

Page 90: ASML C Coding Standard

Rule 6.10.b

Synopsis:Only perform token pasting with the token pasting operator (##).Language:CLevel: 8Category:Preprocessing Directives

Description

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)

Rule 6.10.1.a

Synopsis:Code checker flags shall not be used in the source code.Language:CLevel: 6Category:Preprocessing Directives

Description

Example

#ifdef TICS /* WRONG */

Rule 6.10.1.c

Synopsis:#ifdef, #ifndef, #if defined and #if !defined are not allowed in external header files.Language:CLevel: 3Category:Preprocessing Directives

Description

Justification

title 05/21/22

85

Page 91: ASML C Coding Standard

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 toanother

Rule 6.10.1.e

Synopsis:Don't use "#if 0" as commentsLanguage:CLevel: 7Category:Preprocessing Directives

Description

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 notrecommended because it is not clear why it is commented out. Should it be commented in again at alater stage? Possibly it won't even compile at that time any more. The configuration managementsystem 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 humanbeings that it doesn't concern real code.

Example:

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

Rule 6.10.2.a

Synopsis:All headers files shall be identified by an #include directive.Language:CLevel: 2Category:Preprocessing Directives

Description

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

title 05/21/22

86

Page 92: ASML C Coding Standard

(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 .. */

Rule 6.10.2.b

Synopsis: Including source files is not allowed.Language:CLevel: 6Category:Preprocessing Directives

Description

Justification

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

Example

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

Rule 6.10.2.c

Synopsis: It is forbidden to include hpp files in C files.Language:CLevel: 5Category:Preprocessing Directives

Description

Justification

The file extension "hpp" is reserved for C++ header files only. By including a file with extension "hpp" in aC 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 */

title 05/21/22

87

Page 93: ASML C Coding Standard

Rule 6.10.3.a

Synopsis:Use of macros shall strictly be according to the ANSI C89 macro syntax and within the ANSI C89macro constraints.

Language:CLevel: 2Category:Preprocessing Directives

Description

Justification

Use of macros other than within the strict ANSI C89 syntax and constraints may be acceptable for a certainpre-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 */

Rule 6.10.3.b

Synopsis:#define macros shall only be used for symbolic constants. They shall not be used for function likemacros if a function can be written to accomplish the same task.

Language:CLevel: 2Category:Preprocessing Directives

Description

Justification

Macros might be convenient for the program writer but is confusing for all program readers. If performanceis important, one can consider to use the "inline" keyword to hint the compiler to substitute the code of thefunction into its caller (just like function like macros do). Note that most compilers nowadays are much betterin deciding whether to inline or not to gain performance. Note that this doesn't hold for all compilers.

Exceptions

Some functionality can only be implemented by using macros. If the macro definition contains one of thefollowing constructs this rule is not violated:

title 05/21/22

88

Page 94: ASML C Coding Standard

Stringify operator "#"• Token pasting operator "##"• Predefined macros "__FILE__", "__func__", "__FUNCTION__" or "__LINE__"• "sizeof(a)", where "a" is one of the macro arguments•

These constructs should not be used as a free pass to this rule. The scope of constructs should be limited inthe macro.

Example 1

#define UINT unsigned int /* WRONG typedef should be used */#define BEGIN { /* WRONG */#define END } /* WRONG */

BEGIN /* WRONG */int x = y;END /* WRONG */

Example 2

typedef unsigned long CCBB_ulong; /* RIGHT */#define MAGIC 1.234 /* RIGHT */

Example 3

#define LOG_ERROR(errortext) \ /* RIGHT, using __LINE__ and __FILE__ */ log ("Error occurred at line %d in file %s: %s\n", \ __LINE__, __FILE__, errortext)

#define WARN_IF(expr) \ /* RIGHT, stringification */ if(expr) \ { \ log("Warning: " #expr " was TRUE"); \ }

Rule 6.10.3.c

Synopsis:Any instance of macro parameters, macro body and macro operations shall be enclosed withinparenthesis.

Language:CLevel: 8Category:Preprocessing Directives

Description

Justification

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

Example 1

#define C A + B /* WRONG */

title 05/21/22

89

Page 95: ASML C Coding Standard

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 */

Rule 6.10.3.d

Synopsis:Macros should not end with a semicolon.Language:CLevel: 6Category:Preprocessing Directives

Description

Justification

If a macro definition ends with a semicolon, the macro caller can't use a semicolon after the macro, otherwisethere will be 2 semicolons after macro expansion. Most compilers and code checkers will consider this extrasemicolon as an empty statement and warn about it. The macro caller should use the semicolon because thatmakes 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 */

title 05/21/22

90

Page 96: ASML C Coding Standard

Rule 6.10.3.e

Synopsis:Use a semicolon at the end of a function-like macro call.Language:CLevel: 6Category:Preprocessing Directives

Description

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 */

Rule 6.10.3.2.b

Synopsis:A macro shall not comprise both the "#" and "##" operators simultaneously.Language:CLevel: 2Category:Preprocessing Directives

Description

Justification

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

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. */

Rule 6.10.3.3.a

Synopsis:Result of "##" operator shall be a legal pre-processing token.Language:CLevel: 2Category:Preprocessing Directives

title 05/21/22

91

Page 97: ASML C Coding Standard

Description

Justification

The "##" operator should be used sparingly and with care. In particular there are constraints which operate onthe context in which it may be used. The result of the glue operator should be a valid pre-processing token; soit is not legal, for instance, to glue together an operator to an identifier. Valid pre-processing tokens musthave the lexical form of a header-name, an identifier, a character constant, a string literal, an operator, apunctuator 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 */

Rule 6.10.3.4.a

Synopsis:Recursive macro definitions shall not be used.Language:CLevel: 4Category:Preprocessing Directives

Description

Justification

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

Rule 6.10.3.5.a

Synopsis:Macros shall only be #define'd and #undef'ed at file scope.Language:CLevel: 4Category:Preprocessing Directives

Description

Justification

title 05/21/22

92

Page 98: ASML C Coding Standard

Although macro names are not affected by the C scoping rules, using #define inside a C scope looks veryconfusing - 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 */ ...}

Rule 6.10.4.a

Synopsis:The line splicing character ('\' at the end of a line) shall not be used, except in preprocessormacros.

Language:CLevel: 8Category:Preprocessing Directives

Description

Justification

This construct does not enhance readability in for example string literals. It also prohibits indentation instring 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 */

Example 2

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

Rule 6.10.4.b

Synopsis:When used, the line-splicing character ('\' at the end of a line) shall immediately be followed bythe newline character.

Language:CLevel: 6Category:Preprocessing Directives

title 05/21/22

93

Page 99: ASML C Coding Standard

Description

Justification

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

Example

#define DEFINE_VERY_LONG_MACRO_NAME \ /* comment */ 1234 /* WRONG */

#define DEFINE_VERY_LONG_MACRO_NAME \ 1234 /* RIGHT */

Rule 6.10.4.c

Synopsis:Do not use mixed EOL characters in a file.Language:CLevel: 8Category:Preprocessing Directives

Description

Justification

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

Rule 6.10.6.a

Synopsis:The pragma directive and pragma operator shall not be used.Language:CLevel: 2Category:Preprocessing Directives

Description

Justification

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

title 05/21/22

94

Page 100: ASML C Coding Standard

Rule 6.10.8.b

Synopsis:Only the predefined macro names __FILE__, __LINE__ and __func__ may be used.Language:CLevel: 3Category:Preprocessing Directives

Description

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.

title 05/21/22

95

Page 101: ASML C Coding Standard

LibraryRules

7.2.a The standard header file assert.h shall not be used.

7.12.a The arguments to any mathematical function shall be within the appropriate range.

7.12.b Any calculation result shall not overflow the corresponding output parameter or return value datatype.

7.13.a The setjmp() function and its counterpart longjmp() shall not be used.

7.18.a Do not define types or macros with the same name as types or macros in stdint.h.

7.19.a Only standard output specifiers and standard flags shall be used in output format specifications.

7.19.b The arguments in a formatted output function shall match the output specifiers in the formatspecification.

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

7.19.d The arguments in a formatted input function shall match the input specifiers in the formatspecification.

7.19.e The number of arguments to printf formats should correspond to the actual arguments.

7.19.f Do not access members of type FILE directly.

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

7.21.a Don't use the functions strerror and strtok, instead use their re-entrant counterparts strerror_r andstrtok_r.

7.23.a Don't use the functions asctime, ctime and gmtime instead use their re-entrant counterpartsasctime_r, ctime_r and gmtime_r.

7.26.1.a Don't use the functions readdir instead use the re-entrant counterpart readdir_r

7.26.2.a Don't use the functions rand. Instead use the re-entrant counterpart rand_r.

Rule 7.2.a

Synopsis:The standard header file assert.h shall not be used.Language:CLevel: 4Category:Library

Description

Justification

Usage of macros can lead to uncontrolled termination of code which is prohibited.

Rule 7.12.a

Synopsis:The arguments to any mathematical function shall be within the appropriate range.Language:CLevel: 2

96

Page 102: ASML C Coding Standard

Category:Library

Description

Justification

When supplied a bad argument, the returned value cannot be used, as it is either NAN or an implementationspecific 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){ /* handle error */}else{ c = sqrt(d);}

Note

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

Rule 7.12.b

Synopsis:Any calculation result shall not overflow the corresponding output parameter or return value datatype.

Language:CLevel: 2Category:Library

Description

Justification

title 05/21/22

97

Page 103: ASML C Coding Standard

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

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".

Rule 7.13.a

Synopsis:The setjmp() function and its counterpart longjmp() shall not be used.Language:CLevel: 3Category:Library

Description

Justification

The use of longjmp() results in unstructured code.

Example

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

Rule 7.18.a

Synopsis:Do not define types or macros with the same name as types or macros in stdint.h.Language:CLevel: 4Category:Library

Description

Justification

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

title 05/21/22

98

Page 104: ASML C Coding Standard

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.

Rule 7.19.a

Synopsis:Only standard output specifiers and standard flags shall be used in output format specifications.Language:CLevel: 2Category:Library

Description

Justification

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

Example

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 */

Rule 7.19.b

Synopsis:The arguments in a formatted output function shall match the output specifiers in the formatspecification.

Language:CLevel: 1Category:Library

title 05/21/22

99

Page 105: ASML C Coding Standard

Description

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.

Rule 7.19.c

Synopsis:Only standard input specifiers and standard flags shall be used in input format specifications.Language:CLevel: 2Category:Library

Description

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 */

title 05/21/22

100

Page 106: ASML C Coding Standard

Rule 7.19.d

Synopsis:The arguments in a formatted input function shall match the input specifiers in the formatspecification.

Language:CLevel: 1Category:Library

Description

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 */

Rule 7.19.e

Synopsis:The number of arguments to printf formats should correspond to the actual arguments.Language:CLevel: 1Category:Library

Description

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 */

Rule 7.19.f

Synopsis:Do not access members of type FILE directly.Language:CLevel: 6Category:Library

title 05/21/22

101

Page 107: ASML C Coding Standard

Description

Justification

The FILE struct can be different on different operating systems. Source code should not depend on themember fields. Programs that access for instance the "_fileno" field directly are in risk of accessing anotherfile descriptor and causing unpredictable harm to the system (write to another file, close another file orsocket, 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 */

Rule 7.19.g

Synopsis:Do not use the same buffer for reading and writing when calling input/output functions.Language:CLevel: 1Category:Library

Description

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 */

Rule 7.21.a

Synopsis:Don't use the functions strerror and strtok, instead use their re-entrant counterparts strerror_r andstrtok_r.

Language:CLevel: 4Category:Library

title 05/21/22

102

Page 108: ASML C Coding Standard

Description

Justification

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

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 */

Rule 7.23.a

Synopsis:Don't use the functions asctime, ctime and gmtime instead use their re-entrant counterpartsasctime_r, ctime_r and gmtime_r.

Language:CLevel: 5Category:Library

Description

Justification

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

Example

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

char datebuffer[MIN_BUFFER_SIZE]; /* statically allocated */char *datestring;datestring = asctime_r(&tm, datebuffer); /* RIGHT */

Rule 7.26.1.a

Synopsis:Don't use the functions readdir instead use the re-entrant counterpart readdir_rLanguage:CLevel: 5Category:Library

title 05/21/22

103

Page 109: ASML C Coding Standard

Description

Justification

Non-reentrant functions can cause problems when multiple threads are used or memory is shared betweentasks (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 */

Rule 7.26.2.a

Synopsis:Don't use the functions rand. Instead use the re-entrant counterpart rand_r.Language:CLevel: 5Category:Library

Description

Justification

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

Example

#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.

title 05/21/22

104

Page 110: ASML C Coding Standard

LiteratureStackOverflowTitle: stackoverflow.com

105