DATASHEET
BARR C Rule Enforcement
https://barrgroup.com/embedded-systems/books/embedded-c-coding-standard
ENFORCEMENT HELIX QAC 2024.2
Total | ||
---|---|---|
a | Total Number of Rules | 160 |
b | Total Number of ‘Not Statically Enforceable’ Rules (Assisted/Unassisted) | 137 |
c | Total Number of Enforceable Rules (a-b) | 23 |
d | Total Number of Enforced Rules | 19 |
e | Total Number of Unenforced Rules | 4 |
f | Enforce Rules Percentage (d/c) | 83% |
g | Unenforced Rules Percentage (e/c) | 17% |
Automated
Rule | Rule Description | Enforced |
---|---|---|
BARR1-3-a | Braces shall always surround the blocks of code following if, else, switch, while, do, and for statements. | Yes |
BARR1-2-a | The width of all lines in a program shall be limited to a maximum of 80 characters. | Yes |
BARR1-3-b | Each left brace ({) shall appear by itself on the line below the start of the block it opens. The corresponding right brace (}) shall appear by itself in the same position the appropriate number of lines later in the file. | Yes |
BARR1-7-a | The auto keyword shall not be used. | Yes |
BARR1-7-b | The register keyword shall not be used. | Yes |
BARR2-1-a | Single-line comments in the C++ style are a useful and acceptable alternative to traditional C style comments. | No |
BARR2-1-b | Comments shall never contain the preprocessor tokens. | Yes |
BARR3-5-a | The tab character (ASCII 0x09) shall never appear within any source code file. | Yes |
BARR3-6-a | Whenever possible, all source code lines shall end only with the single character ‘LF’ (ASCII 0x0A), not with the pair ‘CR’-‘LF’ (0x0D 0x0A). | Yes |
BARR3-6-b | The only other non-printable character permitted in a source code file is the form feed character ‘FF’ (ASCII 0x0C). | Yes |
BARR4-1-a | All module names shall consist entirely of lowercase letters, numbers, and underscores. No spaces shall appear within the module’s header and source file names. | No |
BARR4-1-b | All module names shall be unique in their first 8 characters and end with suffices .h and .c for the header and source file names. | Yes |
BARR4-1-c | No module header file name shall share the name of a header file from the C Standard Library or C++ Standard Library. | Yes |
BARR4-1-d | Any module containing a main() function shall have the word “main” as part of its source file name. | No |
BARR4-3-e | Each source file shall be free of unused include files. | No |
BARR5-1-b | All new structures, unions, and enumerations shall be named via a typedef. | Yes |
BARR5-2-b | The keywords short and long shall not be used. | Yes |
BARR5-3-a | Bit-fields shall not be defined within signed integer types. | Yes |
BARR5-3-b | None of the bitwise operators shall be used to manipulate signed integer data. | Yes |
BARR5-3-c | Signed integers shall not be combined with unsigned integers in comparisons or expressions. | Yes |
BARR7-2-a | All variables shall be initialized before use. | Yes |
BARR8-5-a | The use of goto statements shall be restricted as per Rule 1.7.c. | Yes |
BARR8-5-b | C Standard Library functions abort(), exit(), setjmp(), and longjmp() shall not be used. | Yes |
Non-Automated (Not Statically Enforceable)
Rule | Rule Description | Enforced |
---|---|---|
BARR1-4-a | Do not rely on C operator precedence rules, as they may not be obvious to those who maintain the code. Use parentheses to ensure proper execution order within a sequence of operations. | Assisted |
BARR1-1-a | All programs shall be written to comply with the C99 version of the ISO C Programming Language Standard. | Assisted |
BARR1-1-b | Whenever a C++ compiler is used, appropriate compiler options shall be set to restrict the language to the selected version of ISO C. | Unassisted |
BARR1-1-c | The use of proprietary compiler language keyword extensions, #pragma and inline assembly shall be kept to the minimum necessary to get the job done. | Assisted |
BARR1-1-d | Preprocessor directive #define shall not be used to alter or rename any keyword or other aspect of the programming language. | Assisted |
BARR1-4-b | Unless it is a single identifier or constant, each operand of the logical AND (&&) and logical OR (||) operators shall be surrounded by parentheses. | Assisted |
BARR1-5-a | Abbreviations and acronyms should generally be avoided unless their meanings are widely and consistently understood in the engineering community. | Unassisted |
BARR1-5-b | A table of project-specific abbreviations and acronyms shall be maintained in a version-controlled document. | Unassisted |
BARR1-6-a | Each cast shall feature an associated comment describing how the code ensures proper behavior across the range of possible values on the right side. | Assisted |
BARR1-7-c | It is a preferred practice to avoid all use of the goto keyword. | Assisted |
BARR1-7-d | It is a preferred practice to avoid all use of the continue keyword. | Assisted |
BARR1-8-a | The static keyword shall be used to declare all functions and variables that do not need to be visible outside of the module in which they are declared. | Assisted |
BARR1-8-b_i | The const keyword shall be used to declare variables that should not be changed after initialization. | Assisted |
BARR1-8-b_ii | The const keyword shall be used to define call-by-reference function parameters that should not be modified. | Assisted |
BARR1-8-b_iii | The const keyword shall be used to define fields in a struct or union that should not be modified. | Unassisted |
BARR1-8-b_iv | The const keyword shall be used as a strongly typed alternative to #define for numerical constants. | Unassisted |
BARR1-8-c_i | The volatile keyword shall be used to declare a global variable accessible by any interrupt service routine. | Unassisted |
BARR1-8-c_ii | The volatile keyword shall be used to declare a global variable accessible by two or more threads. | Unassisted |
BARR1-8-c_iii | The volatile keyword shall be used to declare a pointer to a memory-mapped I/O peripheral register set. | Unassisted |
BARR1-8-c_iv | The volatile keyword shall be used to declare a delay loop counter. | Unassisted |
BARR2-1-c_i | Code shall never be commented out, even temporarily. | Assisted |
BARR2-1-c_ii | Any line or block of code that exists specifically to increase the level of debug output information shall be surrounded by #ifndef NDEBUG ... #endif. | Assisted |
BARR2-2-a | All comments shall be written in clear and complete sentences, with proper spelling and grammar and appropriate punctuation. | Unassisted |
BARR2-2-b | The most useful comments generally precede a block of code that performs one step of a larger algorithm. A blank line shall follow each such code block. The comments in front of the block should be at the same indentation level. | Unassisted |
BARR2-2-c | end-of-line comments should only be used where the meaning of that one line of code may be unclear from the variable and function names and operations alone. | Unassisted |
BARR2-2-d | The number and length of individual comment blocks shall be proportional to the complexity of the code they describe. | Unassisted |
BARR2-2-e | Whenever an algorithm or technical detail is defined in an external reference, a comment shall include a sufficient reference to the original source to allow a reader of the code to locate the document. | Unassisted |
BARR2-2-f | Whenever a flow chart or other diagram is needed to sufficiently document the code, the drawing shall be maintained with the source code under version control and the comments should reference the diagram by file name or title. | Unassisted |
BARR2-2-g | All assumptions shall be spelled out in comments. | Unassisted |
BARR2-2-h | Each module and function shall be commented in a manner suitable for automatic documentation generation. | Unassisted |
BARR2-2-i_i | Use the following capitalized comment markers “WARNING:” to highlight alerts a maintainer there is risk in changing this code. | Unassisted |
BARR2-2-i_ii | Use the following capitalized comment markers “NOTE:” to highlight descriptive comments about the “why” of a chunk of code—as distinguished from the “how” usually placed in comments. | Unassisted |
BARR2-2-i_iii | Use the following capitalized comment markers “TODO:” to highlight an area of the code is still under construction and explains what remains to be done. | Unassisted |
BARR3-1-a | Each of the keywords if, while, for, switch, return when there is additional program text on the same line. | Unassisted |
BARR3-1-b | Each of the assignment operators =, +=, -=, *=, /=, %=, &=, |=, ^=, ~=, != shall always be preceded and followed by one space. | Assisted |
BARR3-1-c | Each of the binary operators +, -, *, /, %, <, <=, >, >=, ==,!=, <<, >>, &, |, ^, && shall always be preceded and followed by one space. | Assisted |
BARR3-1-d | Each of the unary operators +, -, ++, --, ! , ~ shall be written without a space on the operand side. | Assisted |
BARR3-1-e | The pointer operators * and & shall be written with white space on each side within declarations but otherwise without a space on the operand side. | Unassisted |
BARR3-1-f | The ? and : characters that comprise the ternary operator shall always be preceded and followed by one space. | Unassisted |
BARR3-1-g | The structure pointer and structure member operators -> and . shall be written without a space on the operand side. | Unassisted |
BARR3-1-h | The left and right brackets of the array subscript operator ([ and ]) shall be without surrounding spaces, except as required by another white space rule. | Unassisted |
BARR3-1-i | Expressions within parentheses shall always have no spaces adjacent to the left and right parenthesis characters. | Unassisted |
BARR3-1-j | The left and right parentheses of the function call operator shall always be without surrounding spaces, except that the function declaration shall feature one space between the function name and the left parenthesis to allow that one particular mention of the function name to be easily located. | Unassisted |
BARR3-1-k | Except when at the end of a line, each comma separating function parameters shall always be followed by one space. | Unassisted |
BARR3-1-l | Each semicolon separating the elements of a for statement shall always be followed by one space. | Unassisted |
BARR3-1-m | Each semicolon shall follow the statement it terminates without a preceding space. | Unassisted |
BARR3-2-a | The names of variables within a series of declarations shall have their first characters aligned. | Assisted |
BARR3-2-b | The names of struct, union members shall have their first characters aligned. | Unassisted |
BARR3-2-c | The assignment operators within a block of adjacent assignment statements shall be aligned. | Unassisted |
BARR3-2-d | The # in a preprocessor directive shall always be located at the start of a line, though the directives themselves may be indented within a #if or #ifdef sequence. | Assisted |
BARR3-3-a | No line of code shall contain more than one statement. | Assisted |
BARR3-3-b | There shall be a blank line before and after each natural block of code. | Unassisted |
BARR3-3-c | Each source file shall terminate with a comment marking the end of file followed by a blank line. | Assisted |
BARR3-4-a | Each indentation level should align at a multiple of 4 characters from the start of the line. | Assisted |
BARR3-4-b | Within a switch statement, the case labels shall be aligned and the contents of each case block shall be indented once from there. | Assisted |
BARR3-4-c | Whenever a line of code is too long to fit within the maximum line width, indent the second and any subsequent lines in the most readable manner possible. | Unassisted |
BARR4-2-a | There shall always be precisely one header file for each source file and they shall always have the same root name. | Unassisted |
BARR4-2-b | Each header file shall contain a preprocessor guard against multiple inclusion. | Assisted |
BARR4-2-c_i | The header file shall identify only the procedures, constants, and data types about which it is strictly necessary for other modules to be informed. It is a preferred practice that no variable ever be declared (via extern) in a header file. | Assisted |
BARR4-2-c_ii | The header file shall identify only the procedures, constants, and data types about which it is strictly necessary for other modules to be informed. No storage for any variable shall be allocated in a header file. | Assisted |
BARR4-2-d | No public header file shall contain a #include of any private header file. | Unassisted |
BARR4-3-a | Each source file shall include only the behaviors appropriate to control one “entity”. | Unassisted |
BARR4-3-b | Each source file shall be comprised of some or all of the following sections, in the order listed: comment block, include statements, data type, constant, and macro definitions, static data declarations, private function prototypes, public function bodies, then private function bodies. | Unassisted |
BARR4-3-c | Each source file shall always #include the header file of the same name, to allow the compiler to confirm that each public function and its prototype match. | Assisted |
BARR4-3-d | Absolute paths shall not be used in include file names. | Assisted |
BARR4-3-f | No source file shall #include another source file. | Assisted |
BARR4-4-a | A set of templates for header files and source files shall be maintained at the project level. | Unassisted |
BARR5-1-a | The names of all new data types, shall consist only of lowercase characters and internal underscores and end with ‘_t’. | Assisted |
BARR5-1-c | The name of all public data types shall be prefixed with their module name and an underscore. | Unassisted |
BARR5-2-a | Whenever the width of an integer value matters in the program, one of the fixed width data types shall be used in place of char, short, int, long, or long long. | Assisted |
BARR5-2-c | Use of the keyword char shall be restricted to the declaration of and operations concerning strings. | Assisted |
BARR5-4-a | Avoid the use of floating point constants and variables whenever possible. | Assisted |
BARR5-4-b_i | Use the C99 type names for fixed point datatypes. | Assisted |
BARR5-4-b_ii | Append an ‘f’ to all single-precision constants. | Assisted |
BARR5-4-b_iii | Ensure that the compiler supports double precision. | Unassisted |
BARR5-4-b_iv | Never test for equality or inequality of floating point values. | Assisted |
BARR5-4-b_v | Always invoke the isfinite() macro to check that prior calculations have resulted in neither INFINITY nor NAN. | Unassisted |
BARR5-5-a | Appropriate care shall be taken to prevent the compiler from inserting padding bytes within struct or union types used to communicate to or from a peripheral or over a bus or network to another processor. | Assisted |
BARR5-5-b | Appropriate care shall be taken to prevent the compiler from altering the intended order of the bits within bit-fields. | Assisted |
BARR5-6-a | Boolean variables shall be declared as type bool. | Assisted |
BARR5-6-b | Non-Boolean values shall be converted to Boolean via use of relational operators, not via casts. | Assisted |
BARR6-1-a | No procedure shall have a name that is a keyword of any standard version of the C or C++ programming language. | Assisted |
BARR6-1-b | No procedure shall have a name that overlaps a function in the C Standard Library. | Assisted |
BARR6-1-c | No procedure shall have a name that begins with an underscore. | Assisted |
BARR6-1-d | No procedure name shall be longer than 31 characters. | Assisted |
BARR6-1-e | No function name shall contain any uppercase letters. | Assisted |
BARR6-1-f | No macro name shall contain any lowercase letters. | Assisted |
BARR6-1-g | Underscores shall be used to separate words in procedure names. | Unassisted |
BARR6-1-h | Each procedure’s name shall be descriptive of its purpose. | Unassisted |
BARR6-1-i | The names of all public functions shall be prefixed with their module name and an underscore. | Unassisted |
BARR6-2-a | All reasonable effort shall be taken to keep the length of each function limited to one printed page, or a maximum of 100 lines. | Assisted |
BARR6-2-b | Whenever possible, all functions shall be made to start at the top of a printed page, except when several small functions can fit onto a single page. | |
BARR6-2-c | It is a preferred practice that all functions shall have just one exit point and it shall be via a return at the bottom of the function. | Assisted |
BARR6-2-d | A prototype shall be declared for each public function in the module header file. | Assisted |
BARR6-2-e | All private functions shall be declared static. | Assisted |
BARR6-2-f | Each parameter shall be explicitly declared and meaningfully named. | Assisted |
BARR6-3-a | Parameterized macros shall not be used if a function can be written to accomplish the same behavior. | Assisted |
BARR6-3-b_i | Surround the entire macro body with parentheses in parameterized macros. | Assisted |
BARR6-3-b_ii | Surround each use of a parameter with parentheses in parameterized macros. | Assisted |
BARR6-3-b_iii | Use each parameter no more than once, to avoid unintended side effects in parameterized macros. | Assisted |
BARR6-3-b_iv | Never include a transfer of control in parameterized macros. | Assisted |
BARR6-4-a | All functions that encapsulate threads of execution shall be given names ending with _thread. | Unassisted |
BARR6-5-a | Interrupt service routines (ISRs) are not ordinary functions. The compiler must be informed that the function is an ISR by way of a #pragma or compiler-specific keyword. | Unassisted |
BARR6-5-b | All functions that implement ISRs shall be given names ending with _isr. | Unassisted |
BARR6-5-c | To ensure that ISRs are not inadvertently called from other parts of the software, each ISR function shall be declared static and/or be located at the end of the associated driver module as permitted by the target platform. | Unassisted |
BARR6-5-d | A stub or default ISR shall be installed in the vector table at the location of all unexpected or otherwise unhandled interrupt sources. Each such stub could attempt to disable future interrupts of the same type. | Unassisted |
BARR7-1-a | No variable shall have a name that is a keyword of C, C++, or any other well-known extension of the C programming language. | Assisted |
BARR7-1-b | No variable shall have a name that overlaps with a variable name from the C Standard Library. | Assisted |
BARR7-1-c | No variable shall have a name that begins with an underscore. | Assisted |
BARR7-1-d | No variable name shall be longer than 31 characters. | Assisted |
BARR7-1-e | No variable name shall be shorter than 3 characters. | Assisted |
BARR7-1-f | No variable name shall contain any uppercase letters. | Assisted |
BARR7-1-g | No variable name shall contain any numeric value that is called out elsewhere. | Unassisted |
BARR7-1-h | Underscores shall be used to separate words in variable names. | Unassisted |
BARR7-1-i | Each variable’s name shall be descriptive of its purpose. | Unassisted |
BARR7-1-j | The names of any global variables shall begin with the letter ‘g’. | Assisted |
BARR7-1-k | The names of any pointer variables shall begin with the letter ‘p’. | Assisted |
BARR7-1-l | The names of any pointer-to-pointer variables shall begin with the letters ‘pp’. | Assisted |
BARR7-1-m | The names of all integer variables containing Boolean information shall begin with the letter ‘b’. | Assisted |
BARR7-1-n | The names of any variables representing non-pointer handles for objects shall begin with the letter 'h'. | Unassisted |
BARR7-1-o | In the case of a variable name requiring multiple of the above prefixes, the order of their inclusion before the first underscore shall be [g][p|pp][b|h]. | Unassisted |
BARR7-2-b | It is preferable to define local variables as you need them, rather than all at the top of a function. | Unassisted |
BARR7-2-c | If project- or file-global variables are used, their definitions shall be grouped together and placed at the top of a source code file. | Unassisted |
BARR7-2-d | Any pointer variable lacking an initial address shall be initialized to NULL. | Unassisted |
BARR8-1-a | The comma operator shall not be used within variable declarations. | Unassisted |
BARR8-2-a | It is a preferred practice that the shortest (measured in lines of code) of the if and else if clauses should be placed first. | Unassisted |
BARR8-2-b | Nested if…else statements shall not be deeper than two levels. | Assisted |
BARR8-2-c | Assignments shall not be made within an if or else if test. | Assisted |
BARR8-2-d | Any if statement with an else if clause shall end with an else clause. | Assisted |
BARR8-3-a | The break for each case shall be indented to align with the associated case, rather than with the contents of the case code block. | Unassisted |
BARR8-3-b | All switch statements shall contain a default block. | Assisted |
BARR8-3-c | Any case designed to fall through to the next shall be commented to clearly explain the absence of the corresponding break. | Assisted |
BARR8-4-a | Magic numbers shall not be used as the initial value or in the endpoint test of a while, do…while, or for loop. | Unassisted |
BARR8-4-b | With the exception of the initialization of a loop counter in the first clause of a for statement and the change to the same variable in the third, no assignment shall be made in any loop’s controlling expression. | Assisted |
BARR8-4-c | Infinite loops shall be implemented via controlling expression for (;;). | Assisted |
BARR8-4-d | Each loop with an empty body shall feature a set of braces enclosing a comment to explain why nothing needs to be done until after the loop terminates. | Unassisted |
BARR8-6-a | When evaluating the equality of a variable against a constant, the constant shall always be placed to the left of the equal-to operator (==). | Unassisted |