(610) 584-4261 sales@gimpel.com
Request Evaluation Online Demo
Gimpel Software LLC Logo   Gimpel Software Evaluate Order Support News About

PC-lint Plus Support for CERT® C

PC-lint Plus 1.3 provides support for many of the statically enforceable guidelines of CERT C. Checking for CERT C compliance is easily accomplished by adding a reference to the au-certc.lnt file (distributed with PC-lint Plus) to your existing configuration. This file enables the messages corresponding to CERT C guidelines and adds text to issued messages specifying the rules(s) associated with each applicable message. The au-certc.lnt file is a plain text, human-readable configuration file using standard PC-lint Plus option syntax that can easily be modified to meet the needs of any individual project.

The Reference Manual that ships with PC-lint Plus includes a support matrix detailing the level of support for each guideline as well as the mechanisms by which each guideline is supported.

Violation Analysis and Presentation

Consider the following example:

    #include <stdio.h>

    extern void logger(const char *);
    #define LOG(x) logger(#x)

    void copy(FILE *fp_in, FILE *fp_out, int count) {
        char buf[100];
        int bytes = 0;

        while (bytes < count) {
            int bytes_read = fread(buf, 1, 100, fp_in);
            if (!bytes_read) { break; }
            fwrite(buf, 1, bytes_read, fp_in);
            LOG(bytes = bytes + bytes_read);

When analyzing this example with PC-lint Plus, the reported CERTC violations include (among others):

    warning 2479: attempt to perform write operation on stream after read without
        an intervening reposition [CERT C Rule FIO39-C]
            fwrite(buf, 1, bytes_read, fp_in);
    supplemental 831: stream was read here
            int bytes_read = fread(buf, 1, 100, fp_in);

    note 901: variable 'buf' of type 'char [100]' not initialized by definition
        [CERT C Rule EXP33-C]
        char buf[100];

    warning 2666: expression with side effects passed to unexpanded parameter 1 of
        macro 'LOG': parameter is only used with #/## operators [CERT C Rule PRE31-C]
            LOG(bytes = bytes + bytes_read);

Each violation reported includes the location where the violation occurred, a message number and textual description of the underlying issue, and the CERT C Rule that was violated.

Resolving Violations

The PC-lint Plus Reference Manual contains descriptions of each message and often provides additional guidance that can be used to correct the issue. This information can also be displayed on the command line. For example, to display the description of message 2666, run PC-lint Plus with the option -help=2666 to have PC-lint Plus display the following:

    This message is issued when a function-like macro is invoked with a
    parameter that appears as though it would have side effects if it were
    evaluated but since the corresponding parameter is not expanded in the
    macro definition, no side-effect will occur. E.g.:

        #define DEBUG_VAL(x)

        int process(int i) {
            DEBUG_VAL(++i);  // 2666 - increment doesn't occur
            /* ... */
            return i;

    Since the parameter isn't expanded, ++i is not evaluated and the
    increment does not occur which may be unexpected. If the intention is
    that the side-effect occurs regardless of how the macro is defined, the
    expression provoking the side effect should be placed outside the macro
    invocation. For the purpose of this message, any expression appearing to
    contain a function call is considered to have side-effects.
    Detail is one of "parameter is not referenced in the expansion" or
    "parameter is only used with #/## operators". The message can be
    suppressed based on the value of the detail parameter by using -estring.

The CERT C guidelines document can be consulted for information about the specified Rule.

The issue identified by 2666 is a bug that should be corrected by moving the assignment outside the invocation of the LOG macro.

The issue identified by 2479 is not just a Rule violation but also a bug, the same file pointer was accidentally used to both read from and write to the same file which invokes undefined behavior since there is no intervening reposition operation. The solution is to change fp_in to fp_out in the call to fwrite.

Adding an initializer to buf:

        char buf[100] = {0};

resolves the issue reported by 901 (and will prevent 901 from being issued in future runs).

Handling Deviations

Deviations are instances in the source code where a violation of a Rule has been deemed acceptable. While the deviation process will vary from project to project, deviations can be configured in PC-lint Plus using a very flexible suppression mechanism. Most messages can be suppressed in a variety of ways such as within a file, function, or statement, when referring to a particular symbol or type, or on a particular line. Some types of suppressions require a comment be added to the source code but most do not.

For example, the violation of CERT C Rule EXP33-C (which recommends that variables are initialized in their definition) is reported by message 901 which always includes the name of the variable in the message. To suppress message 901 for variables named buf, the option -esym(901, buf) can be used. To suppress the message anywhere within the function copy, the option -efunc(901, copy) may be used. The appropriate suppression option is added to your project’s configuration file or within a lint comment in the source code containing the offending definition. Commentary can follow this option, perhaps with information related to a formal deviation policy, e.g. -esym(901, buf) "deviation for EXP33-C".

Library Code

PC-lint Plus distinguishes between library code (which by default includes foreign and system headers but can be customized to include any subset of headers and modules) and project code. By default, PC-lint Plus will check both library code and project code for compliance with CERT C. It is often desired to limit checking to project code and this is easily accomplished by resetting the library warning level after referencing the au-certc.lnt file using the options -wlib=4 -wlib=1. Individual messages can also be enabled or disabled for library code just as easily using the -elib and +elib options.

See Also

PC-lint Plus Reference Manual chapters referencing SEI copyrighted material and PC-lint Plus configuration files for SEI CERT C checking incorporate portions of “SEI CERT C Coding Standard Wiki”, Copyright © 1995-2018 Carnegie Mellon University, with special permission from its Software Engineering Institute. Neither the aforemoentioned materials nor any other materials produced or published by Gimpel Software LLC have been reviewed nor endorsed by Carnegie Mellon University or its Software Engineering Institute. See the “Acknowledgements” chapter of the PC-lint Plus Reference Manual for more information.

® CERT is a registered trademark of Carnegie Mellon University