In an earlier blog post, I introduced the concept of automatic enforcement of coding standards by stating that:
Enforcement of coding standards too often depends on programmers already under deadline pressure to be disciplined while they code and/or to make time to perform peer code reviews. … To ensure your selected coding standard is followed, and thus effective, your team should find as many automated ways to enforce as many of its rules as possible. And you should make such automated rule checking part of the everyday software build process.
One of the tools we have found to be indispensible for this purpose is Gimpel Software‘s PC-Lint (and the multi-platform FlexeLint). At just a few hundred dollars per seat, PC-Lint happens to also be one of the least expensive tools we own and thus a source of tremendous value to our team.
The following options can be set (in version 9.00) to assist in the automated enforcement of the identified rules from Barr Group’s Embedded C Coding Standard.
Rule(s) | Tool Configuration Notes |
Which C (1.1) | 975 (unrecognized pragma)
+pragma(name, action) -pragma(name) |
Braces (1.3) | PC-Lint can help identify missing braces through indentation checking:
525 (negative indentation) 539 (did not expect positive indentation) 725 (expected positive indentation) |
Parentheses (1.4) | 665 (Unparenthesized parameter in macro is passed an expression)
773 (Expression-like macro not parenthesized) 821 (Right hand side of assignment not parenthesized) 834 (Operator ‘Name’ followed by operator ‘Name’ is confusing. Use parentheses) 973 (Unary operator in macro ‘Symbol‘ not parenthesized) |
Casts (1.6) | 507, 511, 519 (Size incompatibility in cast)
549, 571, 611 (suspicious cast) 643 (loss of precision in pointer cast) 680 (suspicious truncation in arithmetic expression converted to pointer) 688 (cast used within preprocessor conditional statement) 740, 741 (unusual pointer cast) 920 (cast from ‘type’ to ‘void’) 921-930 (cast from ‘type’ to ‘type’) 1773 (attempt to cast away const or volatile) |
Keywords to avoid (1.7) | -deprecate( keyword, auto, violates coding standard )
-deprecate( keyword, register, violates coding standard ) -deprecate( keyword, goto, violates coding standard ) -deprecate( keyword, continue, violates coding standard ) |
Keywords to Frequent (1.8) | 818 (Pointer parameter could be declared ptr to const)
843 (Variable could be declared as const) 844 (Pointer variable could be declared as const) 952 (parameter could be declared as const) 953 (variable could be declared as const) 954 (pointer variable could be declared as pointing to a const) 765 (external symbol could be made static) |
Comments, Acceptable Formats (2.1) | 602 (comment within comment) |
Alignment (3.2)
Indentation (3.4) |
525 (negative indentation)
539 (did not expect positive indentation) 725 (expected positive indentation) |
Header Files (4.2)
Source Files (4.3) |
451 (header file repeatedly included but does not have a standard include guard)
766 (Include of header file not used in module) 966 (indirectly included header file not used in module) 967 (Header file does not have a standard include guard) |
Fixed Width Integers (5.2)
Signed Integers (5.3) |
569 (Loss of information — Integer bits to Integer bits)
570 (loss of sign, assignment being made from a negative constant to an unsigned quantity) 573 (signed-unsigned mix with divide) 574 (signed-unsigned mix with relational) 701, 703 (shift left of signed quantity) 702, 704 (shift right of signed quantity) 712 (loss of precision, one type is larger than another type) 713 (loss of precision, signed to unsigned) 734 (loss of precision, to a quantity smaller than an int) |
Structure and Unions (5.5) | 38 (Offset of symbol inconsistent — A member of a class or struct appears in a different position (offset from the start of the structure) than an earlier declaration)
39 (Redefinition of symbol conflicts with ‘location’ — a struct or a union is being redefined) |
Function-Like Macros (6.3) | 665 (Unparenthesized parameter in macro is passed an expression)
773 (Expression-like macro not parenthesized) |
Initialization (7.2) | 35 (initializer has side-effects)
133 (too many initializers for aggregate) 134 (missing initializer) 530, 603 (symbol not initialized) 540 (excessive size — a string initializer required more space than what was allocated) 644 (variable may not have been initialized) 651 (potentially confusing initializer) 708 (union initialization) 727, 728, 729, 738 (symbol not explicitly initialized) 771, 772 (symbol conceivably not initialized) 784 (nul character truncated from string — During initialization of an array with a string constant there was not enough room to hold the trailing NUL character) 785, 943 (too few initializers for aggregate) 940 (omitted braces within an initializer) |
Switch Statements (8.3) | 44 (A case or default statement occurred outside a switch)
108 (Invalid context — A continue or break statement was encountered without an appropriate surrounding context) 137 (constant used twice within switch) 408 (type mismatch with switch expression) 744 (switch statement has no default) 764 (switch statement does not have a case) 825 (control flows into case/default) |
Equivalence Tests (8.6) | 720 (Boolean test of assignment) |
As a convenience to readers who follow Barr Group’s Embedded C Coding Standard and may like to use RSM and/or PC-Lint to inexpensively and automatically enforce as many of the rules as possible, here are starter configuration files:
- RSM 7.75 Configuration File: rsm_netrino.cfg
- PC-Lint 9.00 Configuration File: pclint_netrino.lnt