Vector Help

Reference Manual for PC-lint® Plus

4 Options

4.1 Rules for Specifying Options

Options begin with a plus (+) or minus (-), except as for the special !e option. Strings that start with any other character are presumed to be filename arguments. 4

Options are processed in order meaning that an option specified after a filename will not take effect until after that file is processed. The effect of options encountered within a source file are limited to the file in which they appear.

Options may be provided on the command line, via the LINT environment variable, within of indirect files, and within lint comments. In all cases, option parsing follows the same general rules although command line arguments may be subject to shell interpolation before they reach PC-lint Plus so additional quoting may be required for options that include characters that your shell considers special.

4.1.1 Options within Comments

Options may be placed within a source code file embedded within comments having the form:

    /*lint option1 option2 ... optional-commentary */

or

    //lint option1 option2 ... optional-commentary


Options within comments should be space-separated. The optional-commentary should, of course, not begin with a plus, minus, or exclamation point. Note that the ’lint’ within the comment must be lower-case as shown and must lie immediately adjacent to the ’/*’ or ’//’. The /*lint comment may span multiple lines. Note that within indirect files (.lnt files), options need not and should not be placed within a lint comment.

4.1.2 Lint Comments inside of Macro Definitions

Lint comments may appear in the definition of a macro. Lint comments of the form /*lint ... */, when written as part of a macro definition, are not processed immediately but instead are retained and expanded when the macro is used. Lint comments of the form //lint ... are not retained as part of the macro definition and are processed like any other lint comment appearing outside a macro. For example:

#define UNUSED

will result in message 750 (local macro not referenced) if the macro is not used. One way to suppress this message is:

#define UNUSED //lint !e750

The seemingly equivalent:

#define UNUSED /*lint !e750*/

will not work because the C-style lint comment is not processed until the macro is expanded.

Function-like macro arguments are expanded within C-style lint comments appearing inside the macro. For example:

#define SuppressInBlock(...) /*lint --e{__VA_ARGS__} */ 
 
void foo() { 
   SuppressInBlock(438, 529) 
   int i = 0; 
}

will suppress messages 438 and 529 within the body of foo. The -p option can be used to see how the macro is expanded:

void foo() { 
   /*lint --e{438, 529} */ 
   int i = 0; 
}

4.1.3 Options on the Command Line

Options specified on the command line are parsed until the end of the command-line argument, even if a space occurring earlier would normally signify the end of the option. This is to prevent unexpected behavior from options that look properly quoted on the command-line but are provided to PC-lint Plus without quotes due to shell interpolation. For example, the option -"format=%(%f %l %) %t %n: %m" is a valid option but when provided on the command line, some shells may eat the quotes such that PC-lint Plus sees only -format=%(%f %l %)%t %n: %m without the quotes. Because options are separated by spaces, in other contexts this would be interpreted as 5 options (the first being -format=%(%f)), none of which are valid. Since multiple options are not allowed in one command-line argument, PC-lint Plus assumes this is intended to be a single option and will parse it as such.

Shell interpolation can cause other problems that cannot be rectified by PC-lint Plus so it is important to understand your shell’s handling of quoting characters when using non-trivial command-line arguments. You should consider placing your options within indirect (.lnt) files where they will not be subject to shell transfiguration.

4.1.4 Specifying Option Arguments

Some options take a single argument using the option=arg syntax. Options are separated by whitespace so there must not be any unquoted spaces around the = sign or within the value. Multiple arguments options use option(arg1 ,arg2 , ...). In this form, the option is immediately followed by a parenthesized list of comma-separated arguments. In place of parentheses, curly braces or square brackets may be used to delimit the argument list. In place of the comma, an exclamation point (!) may be used to separate option arguments. In the option=arg form, the comma and exclamation symbols do not have any special meaning.

4.1.5 Quoted Options and Arguments

Arguments can be quoted by surrounding the entire argument in double-quotes. Quoting is the only way that arguments may contain whitespace when using the option=arg form (for which a space would normally signify the end of the option). For example:

-message="This is a test"      

will emit the message:

"This is a test"      

(including the quote characters). To obtain the same result without the quote characters being emitted, place the initial quote before the =, e.g.:

-message"=This is a test"      

will emit the message:

This is a test  

The initial quote can be placed anywhere between the ’-’ and the ’=’ to achieve the same effect.

When using an argument list, quoted arguments also suppress the meaning of brace characters and argument separators. For example:

-message( ",!)) )" )  

will emit the message:

,!)) )  

Note that for quoted arguments in parenthesized argument lists, the surrounding quotes are not preserved. For unquoted arguments, the leading and trailing whitespace is removed but whitespace within the argument is preserved. Leading and trailing whitespace is preserved in quoted arguments.

4.1.6 Quotes in Arguments

Quotes (") have no special meaning when appearing inside of an unquoted option, e.g. they do not introduce a quoted region and do not have to be paired. For example:

-esym(714, operator "" _x)    

Suppresses message 714 for the literal operator function associated with the user-literal extension _x. Because the quotes occur in the middle of an unquoted argument, they are taken literally.

Quotes present in quoted arguments are treated as literal quotes as long as they cannot be mistaken for the closing quote of an argument. For example, in the option:

-esym(714, "operator "" _x")  

The two inner quote characters are taken to be literal quotes because what follows is the continuation of the argument. In general, quotes inside of a quoted field are taken as literal unless the next non-whitespace character is a , or !, or is the closing brace character that terminates the parenthesized argument list.

4.1.7 Braces within Argument Lists

The brace characters (, [, {, }, ], and ) must be balanced within a non-quoted argument appearing in a parenthesized argument list. Within an unbalanced region, argument separator characters and unbalanced closing braces are ignored and the brace-enclosed list cannot be terminated. For example:

-message({ this ) does not end the option nor this , the argument })  

Prints the text:

{ this ) does not end the option nor this , the argument }    

Within the unbalanced braced region between the { and }, the , and ) characters do not have any special meaning. Note that the braces that introduced a balanced region are preserved. This balancing is necessary to support options such as:

-function(operator new(r))    

4.1.8 Braces and Quotes

Balanced sequences are not recognized within a quoted region, in other words brace characters have no special meaning in a quoted argument. For example, in:

-message( ")[" )      

the ) in the quoted string does not end the option, neither does the [ introduce a new balanced region.

4.1.9 Brace Types in Brace-Enclosed Argument Lists

Any of the (, {, or [ may be used to start an argument list that will be terminated at the first occurrence of a corresponding unquoted closing brace character that occurs in a balanced region. For example, -message(test), -message{test}, and -message[test] are all equivalent.

4.1.10 Option Display

Because options can be placed in obscure places and then forgotten, the verbosity option -vo can be used to display all options as they are encountered.

4.1.11 Expansion of Environment Variables in Options

Environment variables are expanded when surrounded by percent signs (%), this happens in options and arguments as well as in filenames. This expansion occurs even inside of quoted option strings and braced lists but only when the text between the percent signs corresponds to the name of a defined environment variable.

Environment variables are expanded before options are parsed, which means that the expansion of an environment variable could contain part of an option or even multiple options.

Note that because the expansion of environment variables occurs before the options are processed, a -setenv option will not affect following options in the same line comment. Similarly, a -setenv option appearing in a configuration file will not affect environment variables within the same file (as the environment variables will have been expanded before any -setenv options are processed). In general, we recommend that environment variables be defined at the beginning of processing and not be changed afterwards.

Expansion of environment variables can be disabled by setting the fee flag option to OFF.

The dynamic built-in environment variable %ENCLOSING_DIRECTORY% expands to the absolute path of the enclosing directory of the configuration file, module, or header in which the option appears. Outside of a file, it expands to the current working directory. When using this environment variable as the initial component of larger pathname, we recommend using a forward slash as the directory separator even on Windows. For example, the include option -i%ENCLOSING_DIRECTORY%/library could be placed in a configuration file to add a directory called library present in the same directory as the configuration file to the include search list.

4.1.12 Escaping Special Characters

The characters {}()[],!" have special meanings within options. If the fbe flag is ON, \ (backslash) becomes a special character which disables the special meaning of a subsequent special character which must immediately follow it. When the flag is OFF, the backslash character is interpreted literally.

Note that only option parsing is affected, not option-specific handling of arguments. Even when the flag is ON, a backslash cannot be used to “escape” the meaning of characters significant only to the interpretation of an option argument, e.g. backslash cannot be used to inhibit wildcards in a suppression option.

4.2 Option Reference

The table below summarizes the available PC-lint Plus options. Options that were introduced in PC-lint 9 or earlier are marked — in the version column.




?

displays help




-I

add search directory for #include directives




-$

permit $ in identifiers




-a

set the alignment of various types




-append

append String to diagnostic # when issued




-ar_limit

set the operator arrow depth limit to n

2.0




-astquery

register a Query to be evaluated during AST traversal

2.0




+b

redirect banner output to stdout




++b

produce banner line




-b

suppress banner output




-br_limit

set the bracket depth limit to n

2.0




-build_module_ interface_unit

build a C++ module interface unit

2.1




-cc_limit

set the constexpr call depth limit to n

2.0




-cond

conditionally execute options

1.0




+cpp

add C++ extension(s)




-cpp

remove C++ extension(s)




-cs_limit

set the constexpr step limit to n

2.0




+d

define the preprocessor symbol Name resistant to change via #define




++d

define the preprocessor symbol Name that cannot be #undef’d




-d

define the preprocessor symbol Name with value Value




-deprecate

deprecates the use of Name within Category




-diag_accounting

emit diagnostic accounting data

2025




-dump_message_ list

dumps PC-lint Plus message list to the provided file

1.0




-dump_messages

dumps PC-lint Plus messages to the provided file in the specified format

1.0




+dump_queries

enable dumping of parsed Query ASTs

2.0




-dump_queries

disable dumping of parsed Query ASTs

2.0




!e

disables message # for the current line




-e(

inhibits message #s for the next expression




–e(

inhibits message #s for the entire enclosing expression




+e

re-enables message(s) #




-e

disables a message where # is a message number or pattern




-e{

inhibits message #s for the next statement




–e{

inhibits message #s for the entire enclosing braced region




+ecall

enables the message #s within calls to Function




-ecall

inhibits the message #s within calls to Function




+efile

enables the message #s within File




-efile

inhibits the message #s within File




+efreeze

freeze the message #s and/or warning level(s)




++efreeze

deep freeze the message #s and/or warning level(s)




-efreeze

unfreeze the message #s and/or warning level(s)




+efunc

enables the message #s within the body of Function




-efunc

inhibits the message #s within the body of Function




+egrep

enables the message #s when the message text matches Regex

1.0




-egrep

inhibits the message #s when the message text matches Regex

1.0




+elib

enables message #s in library code




-elib

disables the message #s in library code




+elibcall

enables message #s inside calls to library functions




-elibcall

inhibits message #s inside calls to library functions




+elibmacro

enables message #s issued for library macros




-elibmacro

inhibits message #s issued for library macros




+elibsym

enables message #s issued for library symbols




-elibsym

inhibits message #s issued for library symbols




+emacro

enables message #s within macro expansions




-emacro

inhibits message #s within macro expansions




–emacro

inhibits message #s within macro expansions




-env_pop

pop the current option environment

1.0




-env_push

push the current option environment

1.0




-env_restore

restore the option environment to a previously saved one

1.0




-env_save

save the current option environment with name Name

1.0




+equery

enables the message #s when Query matches

2.0




-equery

inhibits the message #s when Query matches

2.0




+estring

enables the message #s parameterized by String




-estring

inhibits the message #s parameterized by String




+esym

enables the message #s parameterized by Symbol




-esym

inhibits the message #s parameterized by Symbol




+etype

enables the message #s parameterized by Type




-etype

inhibits the message #s parameterized by Type




-exitcode

set the exit code to n

1.0




+ext

set the extensions to try for extensionless files




+f

turns a flag on




++f

increments a flag




-f

turns a flag off




–f

decrements a flag




-fallthrough

ignores switch case fallthrough when used in a lint comment




+fatal_error

triggers an unsuppressible fatal error using message 399

1.3




-fatal_error

triggers a suppressible fatal error using message 398

1.3




-father

a stricter version of -parent




-format

sets the message format for height 3 or less




-format4a

sets the format of the message that appears above the error for height 4




-format4b

sets the format of the message that appears below the error for height 4




-format_category

set format for message category

1.2




-format_intro

sets the format of the line that appears before each new message set




-format_stack

sets the format of the stack usage message




-format_summary

format of the output produced by the -summary option




-format_ verbosity

sets the format of verbosity output




-function

copy or remove semantics from Function0




+group

adds messages from Pattern to message group Name

1.0




-group

remove Pattern from group Name or delete Name

1.0




-h

adjusts message height options




-header

auto-include Filename at the beginning of each module




–header

clears previous auto-includes and optionally adds a new one




+headerwarn

causes message #829 to be issued when Filename is #included




-help

display detailed help about Option

1.0




+html

emit HTML output




-i

add search directory for #include directives




–i

add lower-priority search directory for #include directives




-ident

add identifier characters




-idlen

specifies the number of meaningful characters in identifier names




-incvar

change the name of the INCLUDE environment variable to Name




-index

establish ixtype as index type




-indirect

process File as an options file




-lang_limit

specify minimum language translation limits

1.0




+libclass

add class of headers treated as libraries




+libdir

specify a Directory of headers to treat as libraries




-libdir

specify a Directory of headers to not treat as libraries




+libh

specify Headers to treat as libraries




-libh

specify Headers to not treat as libraries




+libm

specify Modules to treat as libraries




-libm

specify Modules to not treat as libraries




-library

indicates the next source module is to be treated as library code




++limit

locks in the message limit at n




-limit

set the message limit to n




+lnt

add indirect file extension(s)




-lnt

remove indirect file extension(s)




-locker_tag

specify alternate locker tag class names

1.4




-max_threads

set the maximum number of concurrent threads for parallel analysis

1.0




+message

emits a custom message with the specified message #




-message

emits a custom message via info 865




+metric

create, check, or nominate a metric

2.0




+metric_report

enable metric report

2.0




+misra_interpret

enable MISRA interpretation

1.2




-misra_interpret

disable MISRA interpretation

1.2




-mutex_attr

specify shared/recursive values used for pthread_mutexattr_settype

1.4




-mutex_init

specify alternate pthread mutex initialization macro names

1.4




+oe

redirect stderr to Filename in append mode




-oe

redirect stderr to Filename overwriting existing content




+os

redirect stdout to Filename in append mode




-os

redirect stdout to Filename overwriting existing content




-p

just preprocess




+paraminfo

include parameter information for specified messages as verbosity

1.0




-paraminfo

exclude parameter information for specified messages as verbosity

1.0




-parent

augment strong type hierarchy




+pch

designates a given header as the pre-compiled header, forcing recreation




-pch

designates a given header as the pre-compiled header, creating precompiled form if needed




-pp_sizeof

set the value that sizeof(Text) evaluates to in a preprocessor directive

1.0




+ppw

enable preprocessor keyword(s)




-ppw

disable preprocessor keyword(s)




–ppw

remove built in meaning of preprocessor keyword(s)




-ppw_asgn

assign preprocessor word meaning of Word2 to Word1




+pragma

associates Action with Identifier for #pragma




-pragma

disables pragma Identifier




-printf

specified names are printf-like functions with format provided in the Nth argument




-restore

restores the state of error inhibition settings




+rw

enable reserved word(s)




-rw

disable reserved word(s)




–rw

remove built in meaning of reserved word(s)




-rw_asgn

assigns reserved word meaning of Word2 to Word1




-s

set the size of various types




-save

saves the current state of error inhibition settings




-scanf

specified names are scanf-like functions with format provided in the Nth argument




-sem

associates the semantic Sem with Function




-setenv

set environment variable name to value




-size

set static or auto size thresholds




-skip_function

skips the body of a Function when parsing

1.0




-specific_climit

maximum number of specific calls per function




+stack

enable stack reporting




-stack

set stack reporting options




-std

specifies the C or C++ language version

1.0




-strong

imbues typedefs with strong type checking characteristics




-subfile

process just options or just modules from options file File




-summary

outputs a message summary at the end of processing, optionally to a file




-t

sets tab width




-thread_report

enable a thread analysis report

1.4




-tr_limit

set the template recursion limit to n




+typename

includes the types of symbols when emitting specified messages




-typename

excludes the types of symbols when emitting specified messages




-u

undefine the preprocessor symbol Name




–u

ignore past and future #defines of the preprocessor symbol Name




-unit_check

unit checkout

1.0




–unit_check

unit checkout and ignore modules in lower .lnt files

1.0




-unreachable

ignores unreachable code when used in a lint comment




+v

output verbosity to stderr and stdout




-v

turn off verbosity or send it to stdout




-verbosify

print string as a verbosity message

1.0




-vt_depth

specifies the maximum number of nested specific walks

1.0




-vt_passes

specifies the number of passes for intermodule value tracking

1.0




-w

sets the base warning level




-width

sets the maximum output width and indentation level for continuations




-wlib

sets the base warning level for library code




-write_file

write String to file Filename

1.0




+xml

activates XML escape sequences




-zero

sets exit code to 0




+zero_err

specify message numbers that should not increment exit code




-zero_err

specify message numbers that should increment exit code








4.3 Message Options

4.3.1 Error Inhibition

-e# disables a message where # is a message number or pattern
+e# re-enables message(s) #

For example, -e504 will turn off error message 504 . The number designator may contain the wild card characters ? (single character match) or * (multiple character match). For example -e7?? will turn off all 700 level errors.5

As another example:

-e1*  

suppresses all messages beginning with digit 1. This includes messages 12 , 1413 and 1 itself. The use of wild card characters is also allowed in -esym , -elib , -elibsym , -efile , -efunc , -emacro , -e(#) , –e(#) , -e{#} and –e{#} .


!e# disables message # for the current line

One-line message suppression (where # is a message number) is designed to be used in a /*lint or //lint comment. It serves to suppress the given message for one line only. For example:

if( x = f(34) ) //lint !e720 
   y = y / x;

will inhibit message 720 for one line. This takes the place of having to use two separate lint comments as in:

//lint -save -e720 
if( x = f(34) )    //lint -restore 
   y = y / x;

Multiple error message suppression options are permitted as in the following, but not wild card characters.

n = u / -1; //lint !e573 !e713

A limitation is that the one-line message suppression may not be placed within macros. This is done for speed. A rapid scan is made of each non-preprocessor input line to look for the character ’!’. If this option could be embedded in a macro, such a rapid search could not be done.

The supplemental messages 893 , 894 , and 897 are immune to direct one-line suppressions. A message suppressed by a one-line suppression, as with any other form of suppression, will also suppress any supplemental messages that would have accompanied it (including those immune to direct one-line suppression).


-e(# [[,]#...]) inhibits message #s for the next expression

This is presumably used within a lint comment. For example:

a = /*lint -e(413) */ *(char *)0;      

will inhibit Warning 413 concerning the use of the Null pointer as an argument to unary *. Note that this message inhibition is self-restoring so that at the end of the expression, Warning 413 is fully restored. Because of this restoration, there is no need for an option +e(#).

This method of inhibiting messages is to be preferred over the apparently equivalent:

a = /*lint -save -e413 */ *(char *)0 
     /*lint -restore */;

The phrase ’next expression’ may require further elaboration. It may suffice to say that there should be no surprises. In particular, it may be any fully parenthesized expression, any function call, array reference, structure reference, or unary operators applied to such expressions. It will stop short of any unparenthesized binary (or ternary) operator.

The -e(, –e(, -e{, and –e{ options are only effective for messages issued during the analysis phase, they cannot be used to suppress messages issued during the preprocessing phase or the semantic analysis phases. This is because expressions do not exist during the preprocessing phase and expression and statement ranges are not established until after semantic analysis has completed. If these options are used with an inappropriate message number, a bad option error will be emitted.


–e(# [[,]#...]) inhibits message #s for the entire enclosing expression

For example:

a = /*lint --e(413) */ *(int *)0 + *(char *)0;  

will inhibit both Warning 413 ’s that would normally occur in the given expression statement. Had the option -e(413) been used instead of –e(413) then only the first Warning 413 would have been inhibited.

The entire expression can be an if clause, a while clause, any one of the for clauses, a switch clause or an expression statement.

The limitations described for the -e(#) option above apply to this option as well.


-e{# [[,]#...]} inhibits message #s for the next statement

This is presumably used within a lint comment. Consider the following example:

//lint -e{715} suppress "k not referenced" 
 
void f(int n, unsigned u, int k)  // 715 not issued 
{ 
   //lint -e{732} suppress "loss of sign" 
   u = n;       // 732 not issued 
 
   //lint -e{713} suppress "loss of precision" 
   if (n) { 
      n = u;  // 713 not issued 
   } 
}

The -e{715} is used to suppress message 715 over the entire function but not subsequent functions. The -e{732} is used to suppress message 732 in the assignment that follows. The -e{713} is used to suppress message 713 over the entire if statement that follows.

Note that this construct can be used before a class definition or namespace declaration to inhibit messages associated with that class or namespace body.

Wild card characters may be used with -e{}. Thus -e{7??} or -e{*} are legitimate.

Note that -emacro( {#}, symbol ) will indirectly result in the -e{#} being used. See -emacro({#}, symbol)

Note that since /*lint */ options that appear in macros are retained you may define a macro for error suppression that is parameterized by number. Given the definition:

#define Suppress(n) /*lint -e{n} */    

then,

Suppress(715)  

will suppress message 715 for the next statement or declaration.

The limitations described for the -e(#) option above apply to this option as well.


–e{# [[,]#...]} inhibits message #s for the entire enclosing braced region

This option must be used within a lint comment. The supplied message pattern will be suppressed within the entirety of the nearest enclosing braced region where the comment is placed. A braced region may be a compound statement, function, class, struct, union, or namespace. If the option is not placed within any such braced region, the suppression applies to the module as a whole. Like other options found in lint comments, it does not extend past the end of the module into the next module.

The limitations described for the -e(#) option above apply to this option as well.


-ecall(# [#...], Function [,Function...]) inhibits the message #s within calls to Function
+ecall(# [#...], Function [,Function...]) enables the message #s within calls to Function

This includes the parsing of the function call and any of the arguments to the call. Example:

//lint -ecall(713,f) 
void f(int); 
void h(int); 
void g(unsigned u) { 
   h(u);   // elicits 713: "Loss of precision" 
   f(u);   // 713 suppressed. 
}

Please note the distinction between -ecall and -efunc . The former suppresses within a call expression whereas the latter suppresses within the definition.


-efile(# [#...], File [,File...]) inhibits the message #s within File
+efile(# [#...], File [,File...]) enables the message #s within File

This option is used to suppress messages from being issued within specific files.

For example,

-efile(714, core.c)

will suppress message 714 for symbols defined in core.c

The name provided must match the file name as reported by PC-lint Plus. In particular, if the ffn flag is ON, the full file name is expected to be provided. To explicitly match the base name of the file (with all directory information removed), prefix the filename with a minus (-). Similarly, to explicitly match the full path of the file (as would be reported with +ffn), prefix the filename with a plus (+). For example:

-efile(714, core.c)    

will not work if using +ffn and will not suppress 714 if the file is reported by PC-lint Plus with a directory such as foo/core.c. The option: -efile(714, -core.c) will suppress 714 within any file whose name is core.c, regardless of its location or the value of ffn. Finally:

-efile(714, +/a/b/core.c)      

will suppress 714 only within core.c located in /a/b/. A file whose name begins with - or + can be suppressed by prefixing the name with a backtick(), e.g. -efile(714, ‘+file.c). Wildcards may be used in the File pattern.


+efreeze | +efreeze(#|w# [,#|w#...]) freeze the message #s and/or warning level(s)
-efreeze | -efreeze(#|w# [,#|w#...]) unfreeze the message #s and/or warning level(s)
++efreeze | ++efreeze(#|w# [,#|w#...]) deep freeze the message #s and/or warning level(s)

It is sometimes useful to inhibit error suppression options so that the programmer can view what messages had been suppressed. The +efreeze and ++efreeze options are designed to do precisely this. These options place some or all messages in a frozen state. Frozen messages cannot be the target of subsequent suppression options, i.e. the following options are ignored when applied to a frozen message:

-e 
!e 
-ecall 
-efile 
-efunc 
-egrep 
-elib 
-elibcall 
-elibmacro 
-elibsym 
-emacro 
-estring 
-esym 
-etype

Additionally, moving to a lower warning level with the -w and -wlib options will not suppress frozen messages. Freezing a message doesn’t implicitly enable the message and doesn’t prevent the message from being enabled with e.g. +e# , it only inhibits suppression options encountered while the message is frozen. Note also that only suppression options encountered while the message is frozen are affected, e.g. a -esym option can affect the issuance of a message that is not frozen until after the -esym is encountered.

For example, let file x.c contain:

int f( int n ) 
   { return n & 0; } //lint !e835 suppress Info 835

Normal linting of x.c will not show the anding of a 0 because message 835 has been suppressed with the !e835. However if our command line consists of:

lint +efreeze x.c      

the suppression itself is suppressed and the message will be issued.

The programmer can emerge (presumably temporarily) from a frozen state by using the option -efreeze.

//lint -save -efreeze 
#include <lib.h> 
//lint -restore

In this example, we will temporarily emerge from the frozen condition for the duration of processing lib.h. For this to work the freeze status is one of the settings affected by the -save options.

A super cooled state can be created with the ++efreeze option. This will not admit to any attempt at a thaw. If ++efreeze had been used prior to the above example, the attempt to use -efreeze would have had no effect.

Without any arguments, these options apply to all messages. Their effects can be limited to individual message numbers or messages within a particular warning level by supplying these as arguments. For example, ++freeze(534) will prevent later-appearing options from suppressing message 534 without affecting the frozen status of other messages. To inhibit suppression of error messages, ++efreeze(w1) can be used.


-efunc(# [#...], Function [,Function...]) inhibits the message #s within the body of Function
+efunc(# [#...], Function [,Function...]) enables the message #s within the body of Function

For example:

int f(int n) 
{ 
   return n / 0;  // Error 54 
}

will result in message 54 (divide by 0). To inhibit this message you may use the option:

-efunc( 54, f )

This will, of course, inhibit any other divide by 0 message occurring within the same function.

The -efunc option contrasts with the -esym option, which suppresses messages about a named function or, indeed, about any named symbol, which is parameterized by Symbol within the error message.

Both the error number and the Function may contain wild card characters. See the discussion of the -esym option.

Member functions must be denoted using the scope operator. Thus:

-efunc( 54, X::operator= )    

inhibits message 54 within the assignment operator for class X but not for any other class. Creative uses of the wild card characters can be employed to make one option serve to suppress messages over a wide range of functions, such as all assignment operators, or all member functions within a class. See the discussion in -esym .

There are times when you might want to quote the 2nd argument to efunc and/or escape some of the pattern valued characters. See -esym ... for an explanation and examples.


-egrep(# [#...], Regex [,Regex...]) inhibits the message #s when the message text matches Regex
+egrep(# [#...], Regex [,Regex...]) enables the message #s when the message text matches Regex

The -egrep option will suppress messages when the supplied regular expression matches the text of the message. This is particularly useful when it is desired to suppress a message based on the values of multiple parameters.

Below are some points to consider when employing -egrep:

  • The +egrep option works the same way as -egrep but is used to enable messages.

  • -egrep uses regular expressions, not wild cards, to perform the match. In particular,

    • the wildcard * regular expression equivalent is .*

    • the wildcard equivalent of ? is .?

    • the wildcard equivalent of [abc] is (abc)?

  • Whereas the parameterized suppression options match the full text of the parameter, the -egrep option by default matches any part of the message. An anchored match can be accomplished using the ^ and $ anchoring characters at the start and end of the regular expression.

  • The text that is matched is the text that corresponds to the %m specifier in the -format option. This includes the full message text (after parameter substitution) as well as any appended text introduced via the -append option but not text injected via the +typename option.

  • The PCRE (Perl) regular expression syntax is used for the regular expressions supported by -egrep.

For example, message 9078 (cast between pointer type Type and integer type Type) is given whenever there is a cast between pointer and integer types. If it is desired to suppress the message only for converting to an int, there is no way to accomplish this using -etype . -etype(9078, int) will suppress the message in such cases but will also suppress cases where an int type is converted from because there is not a way to specify which of the type parameters the -etype option should operate on. In such a case, -egrep may be used as in

-egrep(9078, "type .* and integer type 'int'$")


-elib(# [,#...]) disables the message #s in library code
+elib(# [,#...]) enables message #s in library code

See Chapter 5 Libraries . This is handy because library headers are usually "beyond the control" of the individual programmer. For example, if the stdio.h you are using has the construct

#endif comment  

instead of

#endif /*comment*/    

as it should, you will receive message 544 . This can be inhibited for just library headers by -elib(544). # may contain wild cards. However, a more convenient way to set a level of checking within library code is via -wlib(level) . See also -elibsym() .

This option might not always be necessary since functions defined in library regions are not always fully analyzed by default, meaning messages will not always be issued inside these function definitions. See flag +flf for more information.


-elibcall(# [,#...]) inhibits message #s inside calls to library functions
+elibcall(# [,#...]) enables message #s inside calls to library functions

This option is similar to -ecall but suppresses the specified messages from calls to all library functions.


-elibmacro(# [,#...]) inhibits message #s issued for library macros
+elibmacro(# [,#...]) enables message #s issued for library macros

This option is like -emacro(#,symbol) except that it applies to all macros defined in library code. Like -emacro , you may use a form beginning with . The # may be surrounded with parens or with curly braces and these have the same meaning as with -emacro . E.g.

//lint -elibmacro({414},{54},835) 
//lint ++flb        // Enter Library region 
#define A() ( 1 / 0 ) // macro becomes a library macro 
//lint --flb        // Leave Library region 
int j = A() ;       // No message issued.

Please note that:

-e123  +elibmacro(123)  

does not do what you might think. A +elibmacro only undoes a previous -elibmacro that affected the same message number. There is no way currently of enabling a message for only library macros.


-elibsym(# [,#...]) inhibits message #s issued for library symbols
+elibsym(# [,#...]) enables message #s issued for library symbols

For example, suppose a library defines a pair of classes:

class X { }; 
class Y : public X { ~Y(); };

This will result in message 1790 , public base ’X’ of ’Y’ has no non-destructor virtual functions. Note that the message is deferred until derived class Y is seen. The option -elib(1790) will suppress this message while processing library headers. If in the user’s own code there is a declaration:

class Z : public X { ~Z(); };

the diagnostic will be issued in spite of the fact that -elib(1790) is given because we are outside library code. The user may suppress this by using -esym( 1790, X ). But if there are a large number of such base classes, the user may prefer to issue the option:

-elibsym( 1790 )      

which in effect does an -esym(1790,s) for all library header symbols s.

Please note that:

-e123  +elibsym(123)  

does not do what you might think. A +elibsym only undoes a previous -elibsym that affected the same message number. There is no way currently of enabling a message for only library symbols.


-emacro(# [#...], Symbol [,Symbol...]) inhibits message #s within macro expansions
+emacro(# [#...], Symbol [,Symbol...]) enables message #s within macro expansions
–emacro(# [#...], Symbol [,Symbol...]) inhibits message #s within macro expansions

Suppresses message # in the expansion of the specified macros. The option must precede the macro definition. The option -emacro(#,symbol,...) is designed to suppress message number # for each of the listed macros. For example,

-emacro( 778, TROUBLE )

will suppress message 778 when expanding macro TROUBLE.

Note that the -emacro options only suppress messages within macro expansions. In particular, to suppress a message that mentions the name of a macro, use -estring instead.

There are times when you might want to quote the 2nd argument to emacro and/or escape some of the pattern valued characters. See option -esym ... for an explanation and examples.

  • -emacro( (#), symbol, ... ) inhibits, for a macro expression,
    –emacro( (#), symbol, ... ) inhibits, for the entire expression,

    Suppresses message # in the expansion of the specified macros. The macros are expected to be expressions (syntactically).

    The form of this option uses the –e(#) option and this inhibits messages in the entire expression in which it is embedded. Thus, the option

    --emacro( (413), ZERO )

    would be as if we had defined ZERO as:

    #define ZERO /*lint --e(413) */ (* (int *) 0)  

    This has the effect of inhibiting this message for the entire expression in which ZERO is embedded.

  • -emacro( {#}, symbol, ... ) inhibits for a macro statement,
    –emacro( {#}, symbol, ... ) inhibits for a macro within a region,

    Suppresses message # in the expansion of the specified macros. For example, the Swap macro below will swap the values of two integers.

    //lint -emacro( {717}, Swap ) 
    #define Swap( n, m ) do {int _k = n; n=m; m=_k; } while(0)

    By using the do {} while(0) trick the macro can be employed exactly as any function. However, the trick will engender message 717 because of the ’0’ in the while. The message can be suppressed using the curly bracket version of the -emacro option as shown. This rendition will prefix the body of the macro with the lint comment

    /*lint -e{717} */      

    Use of the –emacro( {#} ...) option will cause the lint comment

    /*lint --e{#} */      

    to be prepended to the macro.


-equery(# [#...], Query) inhibits the message #s when Query matches
+equery(# [#...], Query) enables the message #s when Query matches

These options are used to control message suppression based on the result of a Query that is evaluated at message issuance time. The -equery option will suppress messages when the supplied Query evaluates to a truthy value. For example:

   -equery(916, msgTypeParam(2).isVoidPointerType())

will suppress message 916 when the message would be issued with a void pointer as the second type parameter (the description of each message includes the available parameterizations). If the message is anchored to a statement or expression, the corresponding AST node may be inspected within the query. For example, message 523 is issued at a location anchored to the expression that is determined not to have side effects. The following option will suppress this message when it is issued at the site of a call to a virtual function:

   -equery(523, CallExpr().getDirectCallee().CXXMethodDecl().isVirtual())

The +paraminfo option may be used to determine whether a particular message is issued with an accessible AST node.


-estring(# [#...], String [,String...]) inhibits the message #s parameterized by String
+estring(# [#...], String [,String...]) enables the message #s parameterized by String

Consider the following example:

int f(unsigned char c) { 
   if (c < 1000) return 1; 
   else return 0; 
}

This will result in the following message:

warning 650: constant '1000' out of range for operator '<' 
   if (c < 1000) return 1; 
          ^

If we examine message 650 , we see that it is parameterized by an integer and a string. We may use -estring to suppress on the basis of either of these parameters, e.g.:

-estring(650, "<")    

The second argument to -estring means that the 650 will not be issued when the operation (represented by the string parameter) is <.

The -estring option may be used with messages that are parameterized by anything other than type or symbol.


-esym(# [#...], Symbol [,Symbol...]) inhibits the message #s parameterized by Symbol
+esym(# [#...], Symbol [,Symbol...]) enables the message #s parameterized by Symbol

This is one of the more useful options because it inhibits messages with laser-like precision. For example -esym(714,alpha,beta) will inhibit error message 714 for symbols alpha and beta. Messages that are parameterized by the identifier Symbol can be so suppressed. Also, if the fsn flag is ON (See Section 4.11 Flag Options ) messages parameterized by String may also be suppressed. Thus, if you examine Message 714 you will notice that the italicized word ’Symbol’ appears in the text of the message.

It is possible to macroize a lint option in order to remove some of the ugliness. The following macro NOT_REF(x) can be used to suppress message 714 about any variable x.

#define NOT_REF(x)   /*lint -esym( 714, x ) */ 
 ... 
NOT_REF( alpha ) 
int alpha;

For C++, when the Symbol appearing within a message designates a function, the function’s signature is used. The signature consists of the fully qualified name followed, by a list of parameter types (i.e. the full prototype). For example, in the unlikely case that a C++ module contained only:

class X   { 
   void f(double, int); { } 
};

the resulting messages would include:

info 1714: member function 'X::f(double, int)' not referenced

To suppress this message with -esym you must use:

-esym( 1714, X::f )    

The full signature of the Symbol is X::f(double, int). However, its name is X::f, and it is the name of the symbol (signature minus any arguments) that is used for error suppression purposes. Please note that the unqualified name may not be used. You may not, for example, use

-esym( 1714, f )      

to suppress errors about X::f.

A +esym can be used to override a -e# just as a -esym can override a +e#. Thus, an option combination like:

-e714 +esym( 714,alpha )      

will cause 714 to be reported only for alpha.

The suppression (or the enabling) of esym is weighted against the options: -e# , +e# , -elibsym , -efunc , -etype , -estring , -ecall and +efunc . When Lint is about to report a message, it tallies the "votes" from these options (inasmuch as they apply to the current message). Each applicable option beginning with a ’-’ counts as a vote of -1; each beginning with a ’+’ counts as +1. Since several symbols and names can parameterize a message, it is necessary to tally the negative and positive contributions of all appropriate -esym and +esym options. If the net result is less than zero, the message is suppressed. For example:

-esym(648,a*) +esym(648,apple)  

will suppress 648 for all symbols beginning with ’a’ except for "apple".

There are times when you might want to quote the 2nd argument to esym and/or escape some of the pattern valued characters. See Section 4.1.6 Quotes in Arguments for an explanation and examples.


-etype(# [#...], Type [,Type...]) inhibits the message #s parameterized by Type
+etype(# [#...], Type [,Type...]) enables the message #s parameterized by Type

Both # and the Type parameters may contain wild card characters. This option is similar to -esym except that it operates on the name of the symbol’s type as opposed to the name of the symbol. It must be emphasized that this option applies only to Symbol and Type parameters, not Name parameters or other kinds of parameters.

The representation that PC-lint Plus uses to denote a symbol’s type can be obtained by using +typename(#) where # is a message number (or pattern). Note, that it is not necessary to use +typename to inhibit messages with -etype. Example:

//lint -etype(1746,FooSmartPtr<*>) 
template <class T> class FooSmartPtr {}; 
void f(FooSmartPtr<int> a) {} 
// 1746 ("Parameter 'a' could be made const reference") suppressed.

Note that it is possible to suppress a message globally and then enable it for a specific type or types by using the +etype form of the option. See the description of +esym . This, of course, presumes that the message has a symbol or type parameter.


+group(Name [,Pattern...]) adds messages from Pattern to message group Name
-group(Name [,Pattern...]) remove Pattern from group Name or delete Name

A group of messages can be given a name that can be used anywhere that a message number pattern is allowed. The +group option is used to create a new named group or add messages to an existing group. For example,

+group(formats, 495, 496, 497)  

will create a message group named formats that contains the messages 495 , 496 , and 497 . Messages can be added to this group with additional +group options, e.g.

+group(formats, 240?)  

will add the messages 2400-2409 to the formats group. The -group option can be used to remove messages from a group, for example,

-group(formats, 2400)  

will remove 2400 from the formats group.

Group names can be used in an option where a message number pattern is accepted. For example

-esym(formats, vsprintf), -eformats    

-group(name) without any message patterns will delete the named group. For example:

-group(formats)

will remove the group named formats. This is different from removing all messages in a group, which leaves an empty group that may still be referenced in other options. Referencing a deleted group will result in an error.

Group names may contain upper and lower case letters, digits, ., -, and _ but must start with a letter. Group names are considered to be global and are not part of the Option Environment.


-restore restores the state of error inhibition settings

This option restores the state of the error inhibitions settings (see -save ) to their state at the start of the last -save . For example:

/*lint -save -e641 */ 
   some code 
/*lint -restore */

temporarily suppresses Warning 641 . It is better to restore 641 this way than with a +e641 because if 641 had been turned off globally (say, at the command line) this sequence would not accidentally turn it back on. -restore will also pop the most recent -save if any, so that -save -restore sequences can be nested. If there is no corresponding -save in effect at the time -restore is used, an error will be issued.


-save saves the current state of error inhibition settings

The error inhibition settings affected consist of those set with the following options:

           -e#
           +e#
           +efreeze
           -efreeze
           -w#

-save can be used in a recursive option inhibition setting. For example,

#define alpha \ 
   /*lint -save -e621 */ \ 
   something \ 
   /*lint -restore */

within macro alpha will suppress message 621 setting without affecting either the error suppression state or other -save, -restore options. There is no intrinsic limit to the number of successive -save options.

A -save can be used on the command line or in a .lnt file. E.g., suppose we have two modules, divzero1.c and divzero2.c, and suppose both modules contain the expression (1/0), which normally elicits both error 54 ("Division by zero") and warning 414 ("Possible division by zero"). Then, if our project’s .lnt file contains:

-e414 
-save 
-e54 
divzero1.c 
-restore 
divzero2.c

... then PC-lint Plus will issue neither error 54 nor warning 414 while processing divzero1.c. While processing divzero2.c, warning 414 will still be suppressed (because of the -e414 that was issued before the -save), but PC-lint Plus will issue error 54 because that message was not suppressed at the time that we issued the -save to which the -restore option corresponds.

If you have more -restore options than -save options within a module, then the extra -restore options will revert the error state back to what was in effect before the last -save encountered outside a module, if any. If there is no corresponding -save, either inside or outside the module, when a -restore option is encountered, an error will be issued.

Like all options encountered inside a module, the effects of -save and -restore within a module are limited to the module in which they appear. Once the module is finished processing, the suppression state of the next module is the same as it was before the previous module was analyzed regardless of options encountered inside the previous module.

See also -env_push and -env_pop which provide similar functionality but affect a larger portion of the option environment.


-w# sets the base warning level

The warning levels are:

-w0

No messages (except for fatal errors).

-w1

Error messages only – no Warnings or Informationals.

-w2

Error and Warning messages only.

-w3

Error, Warning and Informational messages (this is the default).

-w4

All messages (including Elective Notes).

The default warning level is level 3.

The option -w# will establish a new warning level and affect only those messages in the zone of transition (see below). Thus, the option:

-e521  -e50  -w2      

will have the effect of suppressing 521 , 50 and all Informationals. On the other hand

-e521 -e50 -w1 -w2    

will suppress 50 and all Informationals. Warning 521 will be restored by the -w2 because Warnings are in the zone of transition in going from level 1 to 2.

Because options are processed in order, the combined effect of the two options: -w2 +e720 is to turn off all Informational messages except 720 . Specifying an invalid warning level (one not in the above table) will result in error 72 .

Zones of Transition
A zone of transition is the set of messages that are impacted by moving to a different warning level or library warning level with the -w and -wlib options.

When moving to a higher warning level with -w or a higher library warning level with -wlib, the zone of transition is the set of messages in warning levels (prev-level, new-leve], the ( representing an exclusive bound and ] representing an inclusive bound. For example, if the current warning level is 1 and the -w3 option is used, the zone of transition constitutes the messages in warning levels (1, 3] or levels 2 and 3. Moving to a higher warning level enables all messages in the zone of transition.

When moving to a lower warning level, the zone of transition is [4, new-level) for -w and [prev-level, new-level) for -wlib. Moving to a lower warning level suppresses all messages in the zone of transition (except enabled messages that have been frozen with +efreeze or ++efreeze ). For example, after the options -w3 +e9001 -w2, all messages in warning levels 4 and 3 will be suppressed, including message 9001 because the zone of transition is [4, 2).

Note that using -w or -wlib with the current warning level or library warning level results in an empty zone of transition and as a result has no effect and will result in warning 686 . To suppress all messages in a warning level higher than the current level, first raise the warning level and then lower it to create a zone of transition. For example, if the current library warning level is 1, the options -wlib(4) -wlib(1) will suppress all non-error messages for library regions. This is useful e.g. to suppress MISRA messages from library code when using one of the provided MISRA author configurations.


-wlib(#) sets the base warning level for library code

It will not affect C/C++ source modules. The warning Levels may have the same range of values as -w# and are as follows:

-wlib(0)

No library messages

-wlib(1)

Error messages only (when processing library code.) This is the default

-wlib(2)

Errors and Warnings only

-wlib(3)

Error, Warning and Informational.

-wlib(4)

All messages (not otherwise inhibited).

For example,

-wlib(2)      

is equivalent to

-elib(7??)  -elib(8??)  -elib(9??) 
-elib(17??) -elib(18??) -elib(19??) 
-elib(27??) -elib(28??) -elib(29??) 
-elib(37??) -elib(38??) -elib(39??) 
-elib(8???) -elib(9???)

but easier to type.

Many users complain that they do not wish to be informed of ’lint’ within library headers. In general, you may use -elib to repeatedly inhibit individual messages but this may prove to be a tedious exercise if there are many different kinds of messages to inhibit. Instead you may use

-wlib(1)      

to inhibit all library messages except syntactic errors.

See the section "Zones of Transition" in the description of the -w option for details about which messages are affected, and how, when moving between library warning levels.


4.3.2 Verbosity

-v[acehiotuw#][mf<int>] turn off verbosity or send it to stdout
+v[acehiotuw#][mf<int>] output verbosity to stderr and stdout

Verbosity refers to the frequency and kind of work-in-progress messages. Verbosity can be controlled by options beginning either with -v or with +v.

If -v is used, the verbosity messages are sent to standard out. On the other hand, if +v is used, the verbosity messages are sent to both, standard out and to standard error. This is useful if you are redirecting error messages to a file and want to see verbosity messages at your terminal as well as interspersed with the error messages. For clarity, the options below are given in terms of -v.

Except for the option +v by itself all verbosity options completely replace prior verbosity settings. It just didn’t make sense to treat +v as turning off verbosity.

The general format is: {-+}v[acehiostw#][mf<int>]. There may be zero or more characters chosen from the set "acehiostw#". This is followed by exactly one of "mf" or an integer.

-vn

(where n is some integer) will print a message every n lines. This option implies -vf. This option will also trigger a file resumption message. Example: -v1 will issue a message for each line of source code.

-va...

Will cause a message to be printed each time there is an Attempt to open a file. This is especially useful to determine the sequence of attempts to open a file using a variety of search directories.

-vc...

This will cause a message to be printed each time a function is called with a unique set of arguments. This is referred to as a Specific Call. See Section 8.8 Interfunction Value Tracking

-ve...

Will cause a message to be printed each time a template function is instantiated.

-vf

Print the names of all source Files as they are encountered. This means all headers as well as module names. Thus, -vf implies -vm. This option will indicate which headers are "Library Header Files". See Section 5.1 Library Header Files .

-vh...

At termination of processing the strong type Hierarchy be dumped in an elegant tree diagram. See the example in Section 7.5.1 The Need for a Type Hierarchy .

-vh-...

The ’h’ verbosity flag continues to mean that the strong type hierarchy is dumped upon termination. If the ’h’ is followed immediately by a ’-’ then the hierarchy will be compressed, producing the same tree in half the lines. See Section 7.6 Printing the Hierarchy Tree for an example.

-vi...

Output the names of Indirect files (.lnt) as they are encountered. This letter ’i’ may be combined with others.

-vm

Print the names of Modules (referring to C or C++ source files — translation units) as they are encountered, and the names of C++20 module interface units as they are built. (this is the default).

-vo...

Output Options as they are encountered whether they are inside lint comments or on the command line. The letter ’o’ may be combined with other letters.

-vq...

Emit user-defined verbosity messages via the verbosify operator in Queries .

-vt...

The ’t’ flag may be added to the verbosity option. This will cause a message to be printed each time a template is to be instantiated.

-vu...

This verbosity option causes user-defined verbosity messages to be emitted when using the -verbosify option.

-vw...

This verbosity flag will issue a report whenever a function is to be processed with specific arguments. This is called a Specific Walk. See Section 8.8 Interfunction Value Tracking .

-v#...

The character ’#’ is usually used with ’f’ and will request identification numbers be printed with each file. This is used to determine whether two files are regarded as being the same.

For example:

lint +vof file1 file2 >temp    

will cause a line of information to be generated for each module, each header and each option. This information will appear at the console as well as being redirected into the file temp. But not all systems support such redirection. Fortunately, there is the -os option

lint +vof -os(temp) file1 file2


-verbosify(string) print string as a verbosity message

The -verbosify option causes the provided string to be emitted as a verbosity message if "user" verbosity output is enabled (which can be accomplished using the verbosity option -vu )


4.3.3 Message Presentation

-append(#, String) append String to diagnostic # when issued

This option can be used to append a trailing message (string) onto an existing error message. For example:

-append( 936, - X Corp. Software Policy 371 )  

will append the indicated message to the text of message 936 .

The purpose of this option, as the example suggests, is to add additional information, to a message, that could be used to support a company or standards body software policy. Referring to the example above, when message 936 is issued, the programmer can see that this has something to do with Software Policy 371. The programmer can then look up Policy 371 and obtain supplementary information about the practice that is to be avoided.

Note that this option does not automatically enable the indicated message. This would be done separately with, in this example, the option +e936. When the form of the option is:

-append(errno (name), string)  

the option is parameterized to append the given text only when certain names appear in the Lint output. For example:

-append( 533(elephant), Set this variable to 5 )      

will append the given text only when message 533 is issued for the preprocessor variable "elephant".

Lastly, multiple -append() options will append multiple messages to the specified Lint diagnostic. Consequently:

-append( 123, Shop Rule #149 ) 
-append( 123, Personal Preference #7 )

will add "Shop Rule #149, Personal Preference #7" to message 123.


-format sets the message format for height 3 or less
-format4a sets the format of the message that appears above the error for height 4
-format4b sets the format of the message that appears below the error for height 4

This option is especially useful if you are using an editor that expects a particular style of error message. The format option is of the form -format=... where the ellipsis consists of any ordinary characters and the following special escapes:

%f = the filename (the +ffn flag controls whether full path names are used)
%l = the line number
%t = the message type (Error, Warning, etc.)
%n = the message number
%m = the message text
%c = the column number (bytes from beginning of line)
%C = the column number +1
%% = a percent sign
%(...%) = conditionally include the information denoted by ... if location information is available
\n = newline
\t = tab
\s = space
\a = alarm (becomes ASCII 7)
\q = quote ("")
\\ = backslash ( ’\’ )
\T = introduce a real tab into the output
\e = ASCII escape

For example the default message format is

-"format=%(%f %l %)%t %n: %m"  

Note that the option is surrounded by quotes so that the embedded spaces do not terminate the option. We could have used \s instead, but it is difficult to read.

If the height of the message is 4 (option -h...4), the -format= option will have no effect. To customize the message use options -format4a=... for the line that goes Above the line in error and -format4b=... for the line that goes Below.

The \e escape sequence can be used to embed ANSI escape codes in the message format to modify output color for terminals that support this. If you intend to include terminal escape sequences in the message format to colorize or otherwise style portions of the output then consider using the -cond option with the condition __is_stdout_terminal to avoid escape sequences when output is redirected or piped.

Sample configuration for colors in terminals supporting ANSI escape codes:

-env_push 
   +fbe 
   -format_category(error,"\\e\[1;31m%c") 
   -format_category(warning,"\\e\[1;33m%c") 
   -format_category(info,"\\e\[1;34m%c") 
   -format_category(note,"\\e\[1;35m%c") 
   -format_category(supplemental,"\\e\[1;37m%c") 
   -format="%(%f %l %)%t %n\\e\[0m: \\e\[1;1m%m\\e\[0m" 
   -fbe 
   -width=120 
   -env_save(color_format) 
-env_pop 
 
-cond(__is_stdout_terminal, 
   -env_restore(color_format) 
)


-format_category(category, string) set format for message category

This option provides additional control over the expansion of the %t (message type) specifier used by the -format option. The only format specifier for -format_category is %c which expands to the name of the relevant message category. The default format is simply %c. The result of expanding the format string for this option determines the value %t expands to in the format string for -format. The first argument is the category whose format string is to be set, one of error, warning, info, note, supplemental, or all. The second argument is the format string.

For example, pclp -message=hello will emit:

<command line>  2  info 865: hello 
-message=hello 
^

whereas pclp -format_category[info,abc_%c_xyz] -message=hello will emit:

<command line>  3  abc_info_xyz 865: hello 
-message=hello 
^


-format_intro sets the format of the line that appears before each new message set

A message set consists of a primary message and any supplemental messages that are given in association with the message. -format_intro can be used to produce a line that appears before every new message set, an empty value (the default) results in no introduction line being printed. For example, to separate every message set with 4 dashes, you can use -format_intro=––\n. The same escape sequences supported by -format can be used with -format_intro.


-format_stack sets the format of the stack usage message

This is the report that deals with stack usage. If this option is not given, a default is assumed.

The option has two uses. It can be used to output information in a form that can readily be absorbed into a database or a spread sheet. It can also be used to obtain a tabular display that is more suitable to visual inspection than the default narrative output.

The format string may contain the following escapes:

%f = function name
%a = auto storage requirements
%t = type of function
%n = total stack requirements if computable
%c = function called by %f
%e = an indicator as to whether the function called is external
%% = a percent sign

\n = newline
\t = tab
\s = space
\a = alarm
\q = quote( " )
\\ = backslash

The % formats may be immediately followed by a field width (in a manner reminiscent of the printf function). If the field width is negative the information is left justified in the field. For example:

-"format_stack=%-20f %5a %-20t %5n %c %e"      

will left-justify the function name and the function type in fields of width 20, and right justify the local stack and total stack requirements in fields of width 5.


-format_summary format of the output produced by the -summary option

The escape options usable with -format are also usable with -format_summary.

The available format specifiers are:
    %n = the message Number
    %c = the Count of instances of a message
    %t = the message Type
    %m = the Message text

The default summary format is:

-format_summary="%c\t%t\t%n\t%m"      


-format_verbosity sets the format of verbosity output

Its primary purpose is to allow the user to add font information to the verbosity output. An example of its use can be found in the file env-html.lnt.

The format string may contain the following escapes:

%m = the normal verbosity message

\n = newline
\t = tab
\s = space
\a = alarm
\q = quote(" )
\\ = backslash


-h[s][A/B][a/b][r][I]N adjusts message height options

The optional s means Space (blank line) after each message.

A and B are used to specify the position of the context information relative to the message for message heights 2 and 3. With A, the context appears above the message, and with B, it appears below the message. Context information includes the Source-line and the indicator I.

a and b (meaning above and below, respectively) specify the location of the indicator I with respect to the source line. This is only used for heights of 3 and 4.

The optional r (meaning repeat) will cause the context information to be repeated for each message produced at the same location, otherwise context information will be suppressed for messages with a location corresponding to the most recently emitted context.

The optional I stands for a user-designated string of characters to be used as a horizontal position indicator denoting the position of the error within the source line. I may not start with s, f, r, m, a or b. This string will be embedded within the source line if N == 2 (see below) or will appear on its own line if N > 2. The indicator may contain digits. This might be useful, for example, in producing an ANSI escape sequence to produce a colored cursor.

The very last digit of the -h option is taken to be the height. N is an integer in the range 1 to 4 indicating the height of the messages (as further described below). Note that N is the nominal height of messages. Some messages may be forced to use more lines owing to a finite screen width (See option -width (...) later in this section).

The default height option is -hrB^3.

For N = 4 the error messages have the general form:

File File-name, Line Line-number 
Source-line 
   I 
Error-number:Message

where, if the letter ’a’ had been specified, the indicator I would have been placed above Source-line rather than below.

Example (-hb^4):

File x.c, Line 4 
n = m; 
   ^ 
Error 40: Undeclared identifier (m)

For N = 3, the general form is:

Source-line 
   I 
File-nameLine-numberError-number:Message

Message Example (-hb^3):

n = m; 
   ^ 
x.c 4 Error 40: Undeclared identifier (m)

Message Example (-hB^3):

x.c 4 Error 40: Undeclared identifier (m) 
n = m; 
   ^

Message Example (-ha_3):

   _ 
n = m; 
x.c 4 Error 40: Undeclared identifier (m)

For N = 2, the general form is:

Source-line 
File-nameLine-numberError-number:Message

Example (-h$2):

n = $m; 
x.c 4 Error 40: Undeclared identifier (m)

For N = 1, the general form is the same as for N = 2 except the Source-line is omitted.

Example (-h1): 

x.c 4 Error 40: Undeclared identifier (m)      


+html(sub-option, ...) emit HTML output

The option +html is used when the output is to be read by an HTML browser. An example of the use of this option is shown in the file env-html.lnt. That file will enable you to portray the output of PC-lint Plus in your favorite browser.

With this option, lines that echo user source code (as well as lines that contain the horizontal position indicator) are output in a monospace font. New lines are preceded by the HTML escape "<br>". This affects messages and verbosity that are written to standard out. It does not affect verbosity that is also directed to standard error. That is, some verbosity messages are directed to both standard out and to standard error through use of the +v ... form of the verbosity option. Only the data directed to standard out is affected.

As a reminder, standard out is the normal stdout of PC-lint Plus or, if the -os(filename) option is given, the destination designated by that option. Standard error is the normal stderr or, if the -oe(filename) option is given, the destination designated by that option.

The sub-options are:

  • version(html-version) can be used to designate the version of HTML. Its use is optional. The version identification will be placed within angle brackets and output before the <html> at the start of the output file.

  • head(file) is another optional argument and can be used to supply header information for the HTML output. The file is searched for (in the usual places as if it had been specified on a #include line) and copied into standard output just after the line that contains "<html>" that normally begins an HTML file.


-limit(n) set the message limit to n

This option imposes an upper limit on the number of messages that will be produced. By default there is no limit.


++limit(n) locks in the message limit at n

This is a variation of -limit(n). It locks in the limit making it impossible to reverse by a subsequent limit option.


-message(text) emits a custom message via info 865

Allows the user to issue a special message with message number 865 and the contents of ’text’ at the time this option is encountered. Environment variables are replaced if surrounded by % characters. For example, you might put this in your std.lnt file:

-message(INCLUDE is set to: %INCLUDE%)

Assuming that INCLUDE is set to C:\compiler\include, this would yield an 865 informational message whose text is:

INCLUDE is set to: C:\compiler\include

While macros are not expanded by -message itself, macros may contain embedded lint comments, which may in turn contain a -message option that can be used to inspect the value of a provided macro. For example:

#define MSG(macro) /*lint -message(The value of #macro is macro) */ 
 
#define MAC 100 
MSG(MAC)

will result in message 865 being emitted with the text:

The value of "MAC" is 100      


+message([#,] text) emits a custom message with the specified message #

This option is similar to the -message option except that it can be called with 2 arguments, in which case the first argument is a custom message number in the range of 8000 -8999. A message with the specified message number and text is emitted.


+paraminfo(# [,#...]) include parameter information for specified messages as verbosity
-paraminfo(# [,#...]) exclude parameter information for specified messages as verbosity

For each message number equal to or matching #, this option will cause PC-lint Plus to print verbosity information about each parameter cited in the specified message and the AST node type that the message is anchored to, if any. Example:

//lint -w1 +e9272 
struct A { 
   virtual int foo(int feet); 
}; 
 
struct B : public A { 
   int foo(int meters); 
};

will elicit the message:

note 9272: parameter 1 of function 'B::foo(int)' has different name 
than overridden function 'A::foo(int)' ('meters' vs 'feet') 
int foo(int meters); 
          ^ 
supplemental 891: previous declaration is here 
virtual int foo(int feet); 
                ^

Message 9272 contains several parameters of different types. Using +paraminfo(9272) provides the following parameterization information immediately before the message is emitted:

Parameter info for next message (9272) 
   AST Anchor Node Type: none 
   String parameter 1: '1' 
   Symbol parameter 1: 'B::foo' (CXXMethodDecl) of type 'int (int)' 
   Symbol parameter 2: 'A::foo' (CXXMethodDecl) of type 'int (int)' 
   Symbol parameter 3: 'meters' (ParmVarDecl) of type 'int' 
   Symbol parameter 4: 'feet' (ParmVarDecl) of type 'int'

This can be useful to better understand how messages are parameterized and how suppressions can be applied to specific instances of a message.

The three types of message parameters reported are String, Symbol, and Type. For Symbol parameters with a type, this type is also reported. The parameters reported by +paraminfo are suitable for use in -estring , -esym , and -etype options. For example, any of the options below will work to suppress this instance of message 9272:

-estring(9272, 1)           // the referenced parameter number 
-esym(9272, B::foo)         // the first symbol referenced 
-esym(9272, A::foo)         // the second symbol referenced 
-esym(9272, meters)         // the third symbol referenced 
-esym(9272, feet)           // the fourth symbol referenced 
-etype(9272, int (int))      // the type of the first two symbols 
-etype(9272, int)           // the type of the last two symbols

The AST node type of Symbol parameters are also included in parentheses following the symbol name. This is useful to determine the node types accessible with the msgSymbolParam builtin Query function within -equery and +equery options.

Some messages are issued with locations anchored to a particular AST node. If the "AST Anchor Node Type" is emitted with a value other than none, the corresponding AST node may be accessed via the currentnode operator in a Query supplied to a -equery or +equery option.


-summary | -summary=filename outputs a message summary at the end of processing, optionally to a file

This option causes a summary of all issued messages to be presented after Global Wrap-up processing. If a filename is specified, the output is sent to the named file. If not, output is sent to the same output stream used for normal Lint messages (that is, the one specified by -os or, if no such option was issued, stdout).

For each message issued, the summary information consists of the message number (e.g. 1736 for "redundant access specifier"), the number of times that the message was issued, the message type (e.g., "Error", "Warning", etc.) and the message text. This forms a list of all Lint messages that were issued. The list is preceded by a row of column labels to aid readability.

See -format_summary .


-t# sets tab width

Sets the tab width used for indentation checking. The default tab width is 8, but it can be changed to 4 using -t4.


+typename(# [,#...]) includes the types of symbols when emitting specified messages
-typename(# [,#...]) excludes the types of symbols when emitting specified messages

For each message number equal to or matching #, this option will cause PC-lint Plus to add type information for any and all symbol parameters cited in the specified message. Example:

class A{}; 
void g(A a) {} 
// Lint reports "Info 1746: parameter 'a' in function 'g(A)' 
// could be made const reference" 
//lint +typename(174?) 
void f(A a) {} 
// Lint reports "Info 1746: parameter 'a' of type 'A' in function 'f(A)' 
// of type 'void (A)' could be made const reference"

One of the purposes of this option is to show the user an exact type name to use as an argument to -etype() . See also +paraminfo .


-width(# [,Indent]) sets the maximum output width and indentation level for continuations

An example of the width option is:

-width(99,4)  

The first parameter specifies the width of messages. Lines greater than this width are broken at blanks. A width of 0 implies no breaking. The second number specifies the indentation to be used on continued lines. -width(79,4) is the default setting.


+xml([tag]) activates XML escape sequences

By adroit use of the -format option you may format output messages in xml. See the file env-xml.lnt for an example. This option has two purposes. Special xml characters ("<", ">" "&" " " ", and at this writing) will be escaped (to "&lt;", "&gt;" and "&amp;", "&quot;", and &apos;" respectively) when they appear in the variable portion of the format. Secondly, if tag is not null, the entire output will be bracketed with <tag> ... </tag>. If tag is null this bracketing will not appear.

It is also possible to add a tag in angle brackets that could be used to define, for example, the version of xml. Thus:

+xml(?xml version="1.0" ?) 
+xml(doc)

will produce as a prefix the following two lines.

<?xml version="1.0" ?> 
<doc>

Then, at the end of all the message output the following one line will appear.

</doc>  


4.4 Processing Options

4.4.1 Compiler Adaptation

-lang_limit(C|C++ , limit-name, limit-value) specify minimum language translation limits

The -lang_limit option allows customization of the minimum translation limits reported by message 793 . This option can be used to increase, decrease, or restore the default limits for individual categories when processing C and C++ code.

The first argument is C or C++ indicating which language the change should affect. The second argument is the name of the limit to modify. The third argument is either a non-negative integral value or the special value default indicating that any customized value should be removed, restoring the default for the language. For example:

-lang_limit(C++, function_arguments, 10)      

Will cause message 793 to be emitted whenever a function call with more than 10 arguments is encountered in a C++ file. A value of 0 for limit-value can be used to indicate the lack of a limit. For a list of the supported limits, default values, and limit names for use with this option, see the 17.10 Language Limits section.


-build_module_interface_unit(filename[, module_decl_name]) build a C++ module interface unit

Build a C++20 module interface unit. The optional second argument must be used to provide the name of the module declaration if the module declaration name differs from the file’s base name. A module interface unit must be registered using this option prior to any translation units that import that module interface unit. Building a module interface unit does not automatically subject it to analysis, and non-error messages will not be emitted when building a module interface unit. If a module interface unit is part of your project and its content is within your desired analysis scope, then it should also be listed as a regular source file for analysis in addition to being built using this option for imports.

The addition of C++20 Modules introduces an overlap in terminology between the existing widespread use of the term “module” to refer to C or C++ source files (including frequent use within this documentation) and a reference to C++20 Modules. For clarity, mentions of the bare term “module” throughout the documentation consistently refer to the former sense. References to C++20 Modules functionality are indicated by explicit use of specific terms such as “module interface unit”, “module implementation unit”, “module partition”, “module declaration”, and “C++20 Modules”.

Note that module partitions are not currently supported.


-std={c89|c90|c99|c11|c17|c23|c++98|c++03|c++11|c++14|c++17|c++20|c++23} specifies the C or C++ language version

The supported values for this option are:

  • C: c89, c90, c99, c11, c17, c23

  • C++: c++98, c++03, c++11, c++14, c++17, c++20, c++23

For example, -std=c99 sets the C language version to C99, and -std=c++14 sets the C++ language version to C++14.

Note that both the current C language version and the current C++ language version are always stored independently of each other; this option controls which C language version is used when processing a C file and which C++ language version is used when processing a C++ file. The determination of whether an individual source file is processed as C or C++ is made based on the file extension (see +cpp ) and the value of the fcp flag.


4.4.2 Preprocessor

-d{Name}[={Value}] define the preprocessor symbol Name with value Value

This option allows the user to define preprocessor variables (and even function-like macros) from the command line. The simplified format of this option is:

-dName[=Value]  

where the square brackets imply that the value portion is optional. If =Value is omitted, 1 is assumed. If only Value is omitted as in -dX= then the value assigned is null. For alternative syntax allowing easier use of string literals in the replacement, use -dName{Replacement}. Examples:

-dDOS 
-dalpha=0 
-dX=

These three options are equivalent to the statements

#define DOS 1 
#define alpha 0 
#define X

appearing at the beginning of each subsequent module.

Note that case is preserved. There is no intrinsic limit to the number of -d options. See also the -u ... option.

This option does not provide any functionality over what can be provided through the use of #define within the code. It does allow lint to be customized for particular compilers without modifying source. It also applies globally across all modules, whereas #define is local to a specific module.


+dName[=Value] define the preprocessor symbol Name resistant to change via #define
++dName[=Value] define the preprocessor symbol Name that cannot be #undef’d

For added security ++dName=Value will behave in a similar fashion and, moreover, name cannot be undef’ed.

Using this option you can lock in the definition of function-like macros as well as object macros.

For example, suppose the PC-lint Plus is stumbling badly over the macro

offsetof(s,m)  

First place your definition within a header file under a slightly different name:

#define my_offsetof(s,m) somedefinition...  

Then use the options:

+doffsetof=my_offsetof 
-header( my_offsetof.h )

where my_offsetof.h contains the definition of the my_offsetof macro.

You may also explicitly set function-like macros. See -dName .


-header(Filename) auto-include Filename at the beginning of each module
–header | –header(Filename) clears previous auto-includes and optionally adds a new one

This is useful for defining macros, typedefs, etc. of a global nature used by all modules processed by PC-lint Plus without disturbing any source code. For example,

-header( lintdcls.h )  

will cause the file lintdcls.h to be processed before each module.

The header is not reported as being unused in any given module (even though it may be). It is not considered a library header. An extra option may be needed to make this assertion as follows: +libh(lintdcls.h)

Multiple -header options may be used, and this effect is additive. Files are included in the order in which they are given. However, an option of the form:

--header( Filename )  

will remove all prior headers specified by -header options before adding Filename.

If Filename is absent as in –header then the effect is to erase all prior -header requests.


-idirectory add search directory for #include directives
-Idirectory add search directory for #include directives

Files not found in the current directory are searched for in the directory specified. There is no intrinsic limit to the number of such directories. The search order is given by the order of appearance of the -idirectory options. For example:

-i/lib/

can be used to make sure that all files not found in the current directory are looked up in some library directory named lib. A directory separation character will be appended onto the end of the -i option if not already present. Thus

-i/lib  

is equivalent to the above.

To include blanks within the directory name employ the quote convention (See Section 4.1 Rules for Specifying Options ) as in the following:

-i"program files\compiler"    

Multiple directories may be specified either with multiple -i options or by specifying a semi-colon separated list with a single -i option. (See also +fim )

PC-lint Plus also supports the INCLUDE environment variable, See Section 18.2.1 INCLUDE Environment Variable . Note: Any directory specified by a -i directive takes precedence over the directories specified via the INCLUDE environment variable.

-Idirectory is identical to -idirectory .

As a special case the option -i- is taken as a directive to remove all of the directories established with previous -i options (it has no effect on those directories specified with INCLUDE).


–idirectory add lower-priority search directory for #include directives

All directories specified by -i are searched before directories named by –i. This is to support compilers that always search through compiler-provided library header directories after searching user-provided directories.

Example: suppose there is a header file named ’bar.h’ in both directory ’/foo’ and directory ’local’. Then:

// in std.lnt: 
--i/foo       // search foo with low priority 
-ilocal       // search local with high priority 
// in t.cpp: 
#include <bar.h> // finds the version in 'local'

Thus the priority of the –i option is always lower than the -i option. How does it compare with the INCLUDE environment variable, which is also lower than -i? If the –i option is in an indirect file (.lnt file) it will act as though it had a lower priority than the INCLUDE environment variable. This is because the INCLUDE variable is triggered upon reading the first file. If the –i option is on the command line or in the LINT environment variable it will take priority over the INCLUDE variable.


-incvar(Name) change the name of the INCLUDE environment variable to Name

The environment variable INCLUDE is normally checked for a list of directories to be searched for header files (See Section 18.2 include Processing ). You may use the -incvar(Name) option to specify a variable to be used instead of INCLUDE. For example 

-incvar(MYINCLUDE)    

requests checking the environment variable MYINCLUDE rather than checking INCLUDE.

Limitation: This option may not be placed in an indirect .lnt file or source file. It may be placed on the command line or within the LINT environment variable. The INCLUDE environment variable is processed just before opening the first file.


-pch(Header) designates a given header as the pre-compiled header, creating precompiled form if needed
+pch(Header) designates a given header as the pre-compiled header, forcing recreation

The header name should be that name used between angle brackets or between quotes on the #include line. In particular, if the name on the #include line is not a full path name do not use a full path name in the option. See Section 6.2 Designating the precompiler header .


-pp_sizeof(Text, Value) set the value that sizeof(Text) evaluates to in a preprocessor directive

This option is provided for legacy code and will direct PC-lint Plus on how to evaluate a particular sizeof expression appearing in a preprocessor conditional. See 18.6 Preprocessor sizeof .


-uName undefine the preprocessor symbol Name

For example:

-u_lint

will undefine the identifier _lint, which is normally pre-defined before each module. The undefine will take place for all subsequent modules after the default pre-definitions are established. The observant reader will notice that you may not undefine the name nreachable.


–uName ignore past and future #defines of the preprocessor symbol Name

//lint --uX 
#define X 1 
int y = X;    

will be equivalent to:

int y = X;    

Please note the difference between this option and the -uName option, which undefines any built-in definition for Name but does not affect definitions that Name may acquire in the future.


+ppw(word [,word...]) enable preprocessor keyword(s)
-ppw(word [,word...]) disable preprocessor keyword(s)

This option removes any predefined meaning we may associate with the preprocessor word(s) (Word1, Word2 etc.). If this is followed by a +ppw(word) the word is entered as a no-op rather than one that has a predefined meaning. For example, if your code contains the non-standard preprocessor directive #include_next and if its meaning coincides with that of the GNU compiler, then just issue the option +ppw(include_next). However, if you would rather have it ignore such a preprocessor word, issue the commands:

--ppw(include_next) 
+ppw(include_next)


–ppw(word [,word...]) remove built in meaning of preprocessor keyword(s)

If this is followed by a +ppw(word) the word is entered as a no-op rather than one that has a predefined meaning. For example, if your code contains the non-standard preprocessor directive #dictionary and if its meaning coincides with that of the DEC VMS compiler, then just issue the option +ppw(dictionary). However, if you would rather have it ignore such a preprocessor word, issue the commands:

--ppw(dictionary) 
+ppw(dictionary)


-ppw_asgn(Word1, Word2) assign preprocessor word meaning of Word2 to Word1

This option assigns the preprocessor semantics associated with Word2 to Word1 and activates Word1. E.g.

-ppw_asgn( header, include )  

will then make

#header <stdio.h>      

behave exactly like:

#include <stdio.h>    

The purpose of this option is to support special non-standard preprocessor conventions provided by some given compiler.

Even though Word2 may not be activated it may still have semantics. Thus

-ppw_asgn( INC_NEXT, include_next )    

will assign the semantics associated with the include_next preprocessor directive to INC_NEXT and activate INC_NEXT; all this in spite of the fact that include_next has not been activated (with the +ppw option). See Section 18.4 Non-Standard Preprocessing for descriptions of non-standard preprocessing directives.

The #macro pre-processing directive is not a directive implemented by any compiler to our knowledge. So why, you ask, are we providing this directive? We are providing #macro as a way for programmers to implement arbitrary preprocessor directives by converting directives into macros.

For example, one compiler accepts the following preprocessor directive

#BYTE n = 'a'  

as a declaration of the variable n having a type of BYTE and an initial value of ’a’. The #macro directive will allow us to express #BYTE as a macro and so render the directive as C/C++ code.

The preprocessing directive:

#macro a b c  

will result in the macro invocation

sharp_macro( a b c )  

The word sharp is used as a prefix because the word ’sharp’ is often used to denote verbally the ’#’ character.

We can transfer the properties of #macro to some other actual or potential preprocessing directive using the option ppw_asgn. For example:

-ppw_asgn( BYTE, macro )      

will assign the #macro properties to BYTE (and also enable BYTE as a preprocessing directive). Then the directive

#BYTE n = 'a'  

will result in the macro call:

sharp_BYTE( n = 'a' )  

Presumably there is a macro definition that resembles:

#define sharp_BYTE(s) unsigned char s;  

Such a definition can be placed in a header file that only PC-lint Plus will see by utilizing the -header option.


+pragma(Identifier, Action) associates Action with Identifier for #pragma
-pragma(Identifier) disables pragma Identifier

The +pragma(identifier, Action) option can be used to specify an identifier that will be used to trigger an action when the identifier appears as the first identifier of a #pragma statement. See Section 4.12.7 User pragmas .


4.4.3 Tokenizing

-$ permit $ in identifiers

-ident(chars) add identifier characters

This option allows the user to specify alternate identifier characters. Each character in chars is taken to be an identifier character. For example if your compiler allows @ as an identifier character then you may want to use the option:

-ident(@)      

Option -$ is identical in effect to -ident($) and is retained for historical reasons.


+rw(word [,word...]) enable reserved word(s)
-rw(word [,word...]) disable reserved word(s)

If the meaning of a reserved word being added is already known, that meaning is assumed. For example, +rw(typeof) will enable the reserved word typeof. If the reserved word has no prior known semantics, then it will be passed over when encountered in the source text. As another example:

+rw( __inline, entry )  

adds the two reserved words shown. __inline is assigned a meaning consistent with that of the Microsoft C/C++ compiler. entry is assigned no meaning; it is simply skipped over when encountered in a source statement. Since no meaning is to be ascribed to entry, it could just as well have been assigned a null value as in

-dentry=      


–rw(word [,word...]) remove built in meaning of reserved word(s)

If word has known semantics, remove those semantics. For example, +rw(global) installs the reserved word global with the meaning it has in OpenCL. If you don’t want that meaning but would rather have global ignored, then use the option sequence:

--rw(global) 
+rw(global)


-rw_asgn(Word1, Word2) assigns reserved word meaning of Word2 to Word1

assigns the keyword semantics associated with word2 to word1 and activates word1. E.g.

-rw_asgn( interrupt, _to_brackets )    

will assign the semantics of _to_brackets to interrupt. This will have the effect of ignoring interrupt(21) in the following:

void f( int n ) interrupt(21) { }      

The purpose of this option is to support special non-standard keyword conventions provided by some given compiler. But do not overlook the use of the -d option in this connection. -d (or the equivalent #define) can be more flexible since a number of tokens may be associated with a given identifier.


4.4.4 Parsing

-ar_limit=n set the operator arrow depth limit to n

This option specifies the arrow limit which represents the maximum depth of which calls to operator-> functions are processed. The default value for this option is 256.


-br_limit=n set the bracket depth limit to n

This option specifies the bracket limit. When a nesting of parentheses, square brackets, and curly braces exceeds this limit an error will be emitted. The default value for this option is 256.


-cc_limit=n set the constexpr call depth limit to n

This option specifies the constexpr call limit which represents the maximum call depth of compile-time-evaluated constexpr functions. The default value for this option is 512.


-cs_limit=n set the constexpr step limit to n

This option specifies the constexpr step limit which represents the maximum number of evaluation steps performed during compile-time-evaluated constexpr functions. The default value for this option is 1048576. Exceeding this limit may be the result of an infinite loop in a constexpr function.


-fallthrough ignores switch case fallthrough when used in a lint comment

indicates that the programmer is aware of the fact that flow of control is falling through from one case (or default) of a switch to another. Without such an option Message 825 will be issued. For example:

case 1: 
case 2: n=0;    //setting n to 0 
case 3: n++;

will result in Info 825 on case 3 because control is falling through from the statement above, which is neither a case nor a default. The cure is to use the -fallthrough option:

case 1: 
case 2: n = 0;   //setting n to 0 
//lint -fallthrough 
case 3: n++;

Warning 616 will be issued if no comment at all appears between the two cases. If this is adequate protection, then just inhibit message 825 .


-tr_limit=n set the template recursion limit to n

This option specifies the template recursion limit. When the limit is reached, message 1777 is issued, which reminds you that you may use this option to deepen the level of recursion. See message 1777 for further details. The default value for this option is 1024.


-unreachable ignores unreachable code when used in a lint comment

This is useful to inhibit some error messages. For example, suppose my_exit() does not return. Then:

int f(n) 
   { 
   if(n) return n; 
   my_exit(1); 
   //lint -unreachable 
   }

contains an unreachable indicator to prevent PC-lint Plus from thinking that an implied return exists at the end of the function. An implied return would not return a value but f() is declared as returning int. Note, however, that it would have been better practice to copy the exit semantics to my_exit. Eg.:

-function(exit,my_exit)

In this case the -unreachable option would not have been necessary.


4.5 Data Options

4.5.1 Scalar Data Size

-s set the size of various types

This option allows setting the size of various scalars (short, float, pointers, etc.) for the target machine. The default sizes are for a 32-bit target machine following the ILP32 model. If you are targeting a 32-bit system that uses a different data model, targeting a 64-bit architecture, or targeting an embeddded environment, then you will need to adjust type sizes to match.

For example, an LP64 target would use the size options:

-ss2 -si4 -sl8 -sll8 -sp8

and an embedded system with 16-bit characters might use:

-sb16 -ss1 -si1 -sl1 -sll2 -sp2

Note that the maximum size that can be specified for standard types is 64 bits. Because the size of long long defaults to 8 bytes, any increase in the size of a byte will require a decrease in the size of long long or a size option misconfiguration error will be issued for long long.

In the list below # denotes a small positive integer that represents the size in characters for the corresponding type (except for -sb# where # is in units of bits).

-sb#

The number of bits in a char is #. The default is 8. Note that by the definition of the sizeof operator, sizeof(char) == 1 regardless of #. This value is conceptually similar to the standard macro CHAR_BIT, although your standard library must still define this correctly in a way that matches the value set using this option.

-sbo#

sizeof(bool) becomes #. The default is 1.

-ss#

sizeof(short) becomes #. The default is 2.

-si#

sizeof(int) becomes #. The default is 4.

-sl#

sizeof(long) becomes #. The default is 4.

-sll#

specifies the size of long long. The option -sll# can be used to specify the size of a long long int. The default is 8. Specifying this size also enables the flag +fll .

-sf#

sizeof(float) becomes #. The default is 4.

-sd#

sizeof(double) becomes #. The default is 8.

-sld#

sizeof(long double) becomes #. The default is 8.

-sp#

size of pointers become #. The default is 4. There must be at least one integer type size that matches the pointer size.

-sw#

sizeof(wchar_t) becomes #. The default is 2. Note this only affects a built-in wchar_t.

See -a to specify alignment of types and the relationship between size and alignment.


-size(flags, amount) set static or auto size thresholds

This option causes an Informational message (812, 813, 2712, 1746 or 2713) to be issued whenever a data variable’s size in bytes equals or exceeds a given amount. Flags can be used to indicate the kind of data as follows:

s

static data (Info 812 ). Data can be file scope (extern or static) or declared static and local to a function.

a

auto data (i.e., stack data) (Info 813 ). See also -stack , which can do a comprehensive stack analysis.

p

parameter variable (Info 2712 ). Checks function parameters for types of a size that equal or exceed the given amount.

c

could be reference to const parameter (Info 1746 ). Suppresses the message for function parameters that are trivially copyable types, as defined by the C++ standard [?, class.copy.assign], of a size less than the given amount.

r

return value (Info 2713 ). Checks for functions that return a type with a size that equal or exceed the given amount.


The purpose of the -size option is to detect potential causes of stack overflow (using the ’a’ flag); to flag large contributors to excessively large static data areas (using the ’s’ option); to identify functions that are receiving (using the ’p’ or ’c’ option) or returning (using the ’r’ option) large data types that may be more appropriate to pass by pointer or reference.

E.g. -size(a,100) detects auto variables that equal or exceed 100 bytes. If you have a stack overflow problem, such a test will let you focus on a handful of functions that may be causing the overflow. It does not, however, look at call chains and does not compute an overall stack requirement either of a single function or of a sequence of calls.

Amount is 0 by default. For ’s’, ’a’, ’p’, and ’r’, the corresponding messages are not emitted when amount is 0. For ’c’, no exception is made for message 1746 when amount is 0.


4.5.2 Scalar Data Alignment

-a set the alignment of various types

The address at which an object may be allocated must be evenly divisible by its type’s alignment. For example, if the type int has an alignment of 2 then each int must be allocated on an even byte address.

Alignment has only minimal impact on the behavior of PC-lint Plus. At this writing there are only three messages (958 , 959 and 2445 ) that detect alignment irregularities. But in addition to these it is sometimes essential to get alignment correct in order to know the sizes of compound data structures.

For every size option (see -s ) of the form:

-sType#

(except for -sb#, the byte size) there is an equivalent alignment option having the form:

-aType#

For example, the option

-ai1  

indicates that the alignment of int is 1 byte. An alignment of 1 means that no restriction is placed on the alignment of types. (An alignment of 0 is undefined).

If an alignment for a type is not explicitly given by a -a option, an alignment is deduced from the size of the type. The deduced alignment is the largest power of 2 that evenly divides the type. Thus if the size is 4 the deduced alignment is 4 but if the size is 6 the deduced alignment is 2. This deduction is made just before the first time that alignment (and size) may be needed. An attempt to use the -aType option (or the -sType option) after this point is greeted with Error 686 . For example:

-si8    // sizeof(int) becomes 8 
       // alignment of int also becomes 8 
-ai1    // alignment of int is 8 
-si16   // sizeof(int) becomes 16 
       // alignment of int stays at 1 
-sl24   // sizeof(long) is 24 
       // alignment of long is 8 
-al2    // alignment of long becomes 2


4.6 Miscellaneous Options

4.6.1 File

+cpp(Extension [,Extension...]) add C++ extension(s)
-cpp(Extension [,Extension...]) remove C++ extension(s)

This option allows the user to add and/or remove extensions from the list that identifies C++ modules. By default only .cpp and .cxx are recognized as C++ extensions. (It is as if +cpp(cpp,cxx) had been issued at the start of processing.) For example:

lint a.cpp +cpp(cc) b.cc c.c  

treats a.cpp and b.cc as C++ modules and c.c as a C module. There is no intrinsic limit to the number of different extensions that can be used to designate C++ modules. See also flag +fcp .

Note: If you are using +cpp(.C), i.e. you want to use case to distinguish C++ vs. C on Windows, you need to also turn off the fold file name flag (-fff ).


+ext(Extension [,Extension...]) set the extensions to try for extensionless files

For example,

lint alpha    

will, by default, cause first an attempt to open alpha.lnt. If this fails there will be an attempt to open alpha.cpp. If this fails there will be an attempt to open alpha.cxx. Finally, an attempt to open alpha.c will be made. It is as if the option:

+ext( lnt, cpp, cxx, c )      

had been given on startup.

Minor notes: This has no effect on which extensions indicate that a module is to be regarded as a C++ module. This is done by the options -/+cpp and -/+fcp . Prefixing an extension with a period has no effect. Thus, +ext(lnt,c) means the same as +ext(.lnt,.c) . For Windows, upper-casing the extension also has no effect. Thus, +ext(lnt) has the same effect as +ext(LNT). On Unix, however, case differences do matter. For example, if the Unix programmer wanted both .c and .C extensions to be taken by default he might want to use the option: +ext(lnt,c,C).


+headerwarn(Filename) causes message #829 to be issued when Filename is #included

For example +headerwarn(stdio.h) will alert the programmer to the use of stdio.h. If the option -wlib(1) is in place, as it usually is to stem the flood of Warnings and Informationals emanating from library headers, no message 829 will be issued from within a library header unless you also issue a +elib(829) sometime after the -wlib(1).


-indirect(File [,...]) process File as an options file

Allows you to specify Lint option files to be processed when this option is encountered. This is useful if you want to use an options file within a Lint comment. For example, Lint option files that are appropriate only for a particular configuration may be conditionally included. The code below may appear in some header that is included either in every module or at least the first module. Thus, the header in question can be injected with the -header option.

#ifndef BEEN_HERE 
#define BEEN_HERE 
  #if defined(HAS_LIBRARY_A) 
      //lint -indirect(lib-a.lnt) 
  #elif defined(HAS_LIBRARY_B) 
      //lint -indirect(lib-b.lnt) 
  #else 
      //lint -indirect(lib-default.lnt) 
  #endif 
#endif


+libclass(Identifier [,...]) add class of headers treated as libraries

This option specifies the class of header files that are by default treated as library headers. Arguments can be one of:

    angle (specified with angle brackets),
    foreign (comes from a foreign directory using -i or the INCLUDE environment variable),
    ansi (one of those specified by ANSI/ISO C), or
    all (meaning all header files).

Library headers are not fully analyzed by default, see flag +flf for more information. For more information, see Section 5.1 Library Header Files .


+libdir(Directory [,...]) specify a Directory of headers to treat as libraries
-libdir(Directory [,...]) specify a Directory of headers to not treat as libraries

This option allows you to override +libclass for specified directories. Directory may contain wild cards (’*’ and ’?’). Library headers are not fully analyzed by default, see flag +flf for more information. For more information about library headers, see Section 5.1 Library Header Files .


+libh(Header [,...]) specify Headers to treat as libraries
-libh(Header [,...]) specify Headers to not treat as libraries

This option allows you to override +libclass and +/-libdir for specified headers. Header may contain wild card characters. Library headers are not fully analyzed by default, see flag +flf for more information. For more information about library headers, see Section 5.1 Library Header Files .


+libm(Module [,...]) specify Modules to treat as libraries
-libm(Module [,...]) specify Modules to not treat as libraries

The Module may contain wild card characters. Library modules are not fully analyzed by default, see flag +flf for more information. For more information about library modules, see 5.2 Library Modules .


-library indicates the next source module is to be treated as library code

This option turns ON the library flag for the next module, if given on the command line, or for the rest of the module if placed within a lint comment. Library modules are not fully analyzed by default, see flag +flf for more information. For an example, see Section 5.2 Library Modules . At one time this option was equivalent to the +flb flag. However, there is now a difference. -library designates the file in which it is placed and all files that it may include as having the library property. Thus, if a lint option within a header file contains the -library flag then only that header (and the headers it includes) are affected. It does not affect the including file. With +flb the flag is left on until turned off.


+lnt(Extension [,Extension...]) add indirect file extension(s)
-lnt(Extension [,Extension...]) remove indirect file extension(s)

Modify the list of filename extensions used to indicate indirect files (by default only lnt designates an indirect file). For example, if you want files ending in .lin to be interpreted as indirect files you use the option:

+lnt( lin )    

After such an option, a filename such as alpha.lin will be interpreted as if it had been named alpha.lnt. That is, it will be interpreted as an extension of the command line rather than as a C/C++ program.

This will not affect the sequence of default extensions that are tried. Thus, when the name alpha is encountered, there will not first be a test to see if alpha.lin exists. This is governed by the +ext option.

If you want to remove the name lnt and replace it by lin you need to use the pair of options:

-lnt(lnt)  +lnt(lin)  


-astquery register a Query to be evaluated during AST traversal

Specifies a Query that will be evaluated for visited nodes during traversal of module ASTs. This option may be used to implement custom checks and messages. See Chapter 16 Queries for more information.


-dump_queries disable dumping of parsed Query ASTs
+dump_queries([sub-options]) enable dumping of parsed Query ASTs

Enables or disables AST dumping for subsequently parsed Queries, see Section 16.7.2 Dumping the Query Tree for more information.


4.6.2 Global

? displays help

-b suppress banner output
+b redirect banner output to stdout
++b produce banner line

Unlike most other options, this option must be placed on the command line and not in an indirect file. When PC-lint Plus is run from some environments, the banner line (identifying the version of PC-lint Plus, and bearing copyright and license information) may overwrite a portion of an editing screen. This is because the banner line is, by default, written to standard error whereas the messages are written to standard out and can be redirected. The option +b will cause the banner line to be written to standard out (and hence will become part of the redirected output). The option -b will suppress the banner line completely.

The option +b works well for:

lint +b ... >outfile  

Unfortunately this will not have the intended effect with:

lint +b -os(outfile) ...      

as the banner line is written before the -os option has had a chance to take effect.

++b will deposit the banner line into standard out anywhere it is encountered. Thus:

lint -os(outfile) ++b ...      

will cause the banner line to be placed into outfile. You will also get a banner line in standard error but this can be separately suppressed as in:

lint -b -os(outfile) ++b ...  


-cond(conditional-expr, true-options [,false-options]) conditionally execute options

The -cond option accepts two or three arguments, the first of which is a conditional expression to evaluate when the option is processed, the second is the set of options to execute if the conditional expression evaluates to true, and the third (optional) argument specifies the options to execute if the conditional expression is false.

The conditional expression may contain string and numeric comparisons and string pattern matching using regular expressions. Each operand in an expression is either numeric or a string. A string is any text that is surrounded by single quotes, everything else is numeric. Valid numeric values include anything that the standard C function strtod can parse as well as the literal values true and false, which represent the values 1 and 0 respectively.

The arithmetic operators +, -, *, and / may be used on numeric values within the expression and possess the same meaning and precedence as their corresponding C operators. The / operator performs floating point division, e.g. 1 / 2 will evaluate to 0.5, not 0. The // operator performs integer division and has the same precedence as /. The mod operator performs integer modulus arithmetic and is equivalent to the % operator in C. The fmod operator yields the floating point modulus value of its operands. The unary operators +, -, and ! have the traditional meaning when applied to numeric operands.

The comparison operators <, <=, >, >= and the equality operators == and != can be used on either numeric or string operands. When used with numeric operands, they behave as the corresponding C operators. When used with string operands, they perform lexicographic comparisons. The operands must be of the same type (numeric or string).

The logical operators && and || and the ternary operator ?: are supported and have the same meaning as the corresponding C operators. Parentheses may be used for grouping subexpressions.

The pattern matching operator ~ takes two operands, a subject string on the left-hand side and a pattern on the right-hand side. Both operands must be strings. The result is true if the subject string matches the regular expression pattern and false otherwise. The PCRE (Perl) regular expression syntax is used for the regular expressions supported by the -cond option.

The special identifier __is_stdout_terminal evaluates to 1 if standard output does not appear to have been redirected or piped and 0 otherwise.

The -cond option is often used to conditionally execute options based on the value of defined environment variables. For example, the option:

-cond('%USE_EXTRA%' == '1', extra.lnt)

will cause PC-lint Plus to process the file extra.lnt if the environment variable USE_EXTRA is defined with a value of 1.

In the following example, the WARNING_LEVEL environment variable is always expected to be defined with a value between 1 and 4. If the variable is properly defined, it is used to set the default warning level, otherwise a fatal error is emitted to prevent further processing:

-cond('%WARNING_LEVEL%' ~ '^[1234]$', 
   -w%WARNING_LEVEL%, 
   +fatal_error("WARNING_LEVEL environment variable not properly defined"))


-diag_accounting(sub-options) emit diagnostic accounting data

This option enables the collection of Diagnostic Accounting data and specifies the files in which the collected data should be written. The required sub-options, each of which take a single argument specifying the file in which the below-described data should be written, are:

  • options_output_file - Suppression option data

  • modules_output_file - Analyzed module data

  • messages_output_file - Encountered diagnostics data

  • suppressions_output_file - Suppression objects created from suppression options

  • orbits_output_file - Interactions between suppression objects and encountered diagnostics

  • files_output_file - Information about processed source files

  • metadata_output_file - Metadata about processed accounting information

All arguments are required, a null file (e.g. NUL on Windows and /dev/null on Linux and macOS) may be used to prevent one or more files from being created. Files are created/truncated at the time the option is encountered. Any output file names, except for the metadata file, that are specified with a name ending in ".zst" will have their contents compressed using the ZStandard compression algorithm before being written. The Orbits and Messages files can become very big for large projects that do not employ the exclude_library or exclude_suppressed_library sub-options, compression can reduce the size of these files by a factor of 30 or more.

This option must be specified before any modules are processed.

The optional sub-option diag_queue_size takes a single interger argument which specifies the maximum number of diagnostic encounters to queue before writing out diagnostic and orbit data. A value of 0 specifies no queue limit. The default queue size is 1000.

The optional sub-option exclude_library, if present, will cause library diagnostics and corresponding orbits to be excluded from output. The value of this option is included in the Metadata file.

The optional sub-option exclude_suppressed_library is like exclude_library, but will only exclude suppressed library diagnostics and corresponding orbits to be excluded from output. The value of this option is included in the Metadata file.

The optional sub-option filter_null_orbits, if present, will cause orbit objects with a vote count of zero and a is_dss field with a value of false to be excluded from the Orbits file. The value of this option is included in the Metadata file.

See section 17.11 Diagnostic Accounting for more information.


-dump_messages(file=filename [,format={plain|list|json|yaml|csv|xml}] [,sub-options]) dumps PC-lint Plus messages to the provided file in the specified format

This option writes out the PC-lint Plus message list to the filename specified with the file=filename sub-option. The format sub-option specifies the format to use when writing messages and may be any of plain, list, json, yaml, csv, or xml. Specifying a format of json, yaml, csv, or xml will result in messages being written in the corresponding format (see examples below). A format of plain will result in output similar to the msg.txt file provided with PC-lint 9. A format of list results in a list output containing one message per line with fields separated by tabs. The default format is plain.

The include_commentary sub-option may be used to indicate whether Reference Manual descriptions of each message should be included in the output. The default is to include commentary; include_commentary=false will disable commentary. Note that commentary is not supported for the list format and cannot be disabled for the plain format.

The include_clang_errors sub-option indicates whether messages in the 4xxx, 5xxx, and 6xxx ranges are included in the output. These messages are mapped clang errors that do not contain descriptions and are excluded from the output by default. Use include_clang_errors or include_clang_errors=true to include these messages.

In all cases, messages are written in ascending order of message number.

Examples

-dump_messages(file=msg.txt) will result in output that looks like:

error 1 
unclosed comment 
 
   End of file was reached with an open comment still unclosed. 
 
 
error 2 
unclosed quote 
 
   An end of line was reached and a matching quote character (single or 
   double) to an earlier quote character on the same line was not found.


-dump_messages(file=msg.txt,format=list) looks like:

1      error  unclosed comment 
2      error  unclosed quote 
3      error  #elif without a #if 
5      error  too many #endif directives 
8      error  unclosed #if 
9      error  #elif after #else


-dump_messages(file=msg.txt,format=json) looks like:

[ 
   { 
      "ID" : "1", 
      "CATEGORY" : "error", 
      "TEXT" : "unclosed comment", 
      "COMMENTARY" : "End of file was reached with an open comment still unclosed." 
   }, 
   ... 
]


-dump_messages(file=msg.txt,format=yaml) looks like:

- 
   id: 1 
   category: error 
   text: 'unclosed comment' 
   commentary: | 
      End of file was reached with an open comment still unclosed. 
- 
   id: 2 
   category: error 
   text: 'unclosed quote' 
   commentary: | 
      An end of line was reached and a matching quote character (single or 
      double) to an earlier quote character on the same line was not found.


-dump_messages(file=msg.txt,format=csv) looks like:

"1","error","unclosed comment","End of file was reached with an open comment still unclosed." 
"2","error","unclosed quote","An end of line was reached and a matching quote character (single or 
double) to an earlier quote character on the same line was not found." 
"3","error","#elif without a #if","A #else was encountered not in the scope of a #if, #ifdef or #ifndef."


Note that newlines may be embedded in the commentary field.

-dump_messages(file=msg.txt,format=xml) looks like:

<messages> 
   <message id="1"> 
      <category>error</category> 
      <text>unclosed comment</text> 
      <commentary>End of file was reached with an open comment still unclosed.</commentary> 
   </message> 
   ... 
</messages>


-dump_message_list=filename dumps PC-lint Plus message list to the provided file

-dump_message_list will case PC-lint Plus to write out its list of messages to the provided file. For example, -dump_message_list(mlist.txt) will write the message information for all messages supported by PC-lint Plus to a file named mlist.txt. This file contains one line per message with three fields, delimited by tabs as shown below:

25  error  character constant too long for its type 
29  error  duplicated type-specifier, '__detail__' 
31  error  redefinition of symbol __symbol__ 
32  error  field size (member __symbol__) should not be zero

Parameterized messages show up in the same way that they do when using the -summary option.


-exitcode=n set the exit code to n

By default, PC-lint Plus terminates with an exit code of 0 upon successful completion and an exit code of 1 when terminating prematurely, such as from a fatal error. If the frz flag is turned OFF, PC-lint Plus will instead exit with the total number of messages emitted. This option can be used to specify the exit code that PC-lint Plus should return upon completion (successful or otherwise). This option has no effect if the frz flag is ON. See also -zero , and +zero_err .


+f turns a flag on
-f turns a flag off
++f increments a flag
–f decrements a flag

See Section 4.11 Flag Options .


-fatal_error(message) triggers a suppressible fatal error using message 398

Issues fatal error 398 with the provided text. While a fatal error normally causes execution to terminate immediately, this does not occur if the message is suppressed. Message 398 is one of the few fatal errors for which suppression is permitted.


+fatal_error(message) triggers an unsuppressible fatal error using message 399

Issues fatal error 399 with the provided text. A fatal error causes execution to terminate immediately. Message 399 cannot be suppressed.


-help=Option display detailed help about Option

With no arguments, the -help option produces the same output as the ? option. When provided with the name of an option, help information specific to the provided option is emitted. For example, given -help=+libh, the following will be emitted:

OPTION:  +libh 
GROUP:   Miscellaneous 
CATEGORY: File 
USAGE:   +libh(Header [,...]) 
 
specify Headers to treat as libraries


-max_threads=n set the maximum number of concurrent threads for parallel analysis

The -max_threads option can be used to specify the number of concurrent threads (the default is 1, which essentially disables multi-threading). One thread will be created for each source module, up to the specified maximum. The -max_threads option must appear before the first module to have any effect. See Section 17.9 Parallel Analysis for more information.


-p | -p(width) just preprocess

If this flag is set, the entire character of PC-lint Plus is changed from a diagnostic tool to a preprocessor. The output is directed to standard out, which may be redirected. Thus,

lint -os( file.p ) -p file.c  

will produce in file.p the text of file.c after all # directives are carried out and removed. This may be used for debugging to determine exactly what transformations are being applied by PC-lint Plus.

The optional argument (width) denotes an upper bound on the width of the output lines. For example:

-p(100)

will limit the width of output lines to 100 characters. Splitting is done only at token boundaries. Very large tokens will not be split even if they exceed the nominal line limit. This is so the result can be passed back through lint or some other C/C++ source processor.

In order to track down some complicated cases involving many include headers you may want to use the -v1 verbosity option in connection with -p. Recall (Section 4.3.2 Verbosity ) that -v1 will produce a line of output for every line processed. When you use both options together, as in, for example:

lint -os( file.p ) -v1 -p file.c      

then the single line will be preceded by the name of the file and the line number both enclosed in a C comment. This will enable you to track through every line of every header processed.


-setenv(name=value) set environment variable name to value

will allow the user to set an environment string. The directive is of the form name=value. For example:

-setenv(ROOT_DIR=\home\program\dev)

will set the environment variable ROOT_DIR to the indicated directory. This can be used subsequently in PC-lint Plus options by using the %var% syntax. For example:

-i%ROOT_DIR%\include

establishes a new search directory based on the environment name.

The environment variable setting will last for the duration of the process. See Section 4.1.11 Expansion of Environment Variables in Options for more information.


-skip_function(Function [,Function...]) skips the body of a Function when parsing

Causes the bodies of the named functions to be skipped during parsing. Functions whose bodies are skipped cannot be semantically analyzed. This option is useful if you are using compiler-specific syntax that cannot be easily accommodated by PC-lint Plus and such usage is isolated to a handful of functions. In general it is better to configure PC-lint Plus to appropriately handle compiler-specific peculiarities but this option can be used as a last resort. See also the flf flag to automatically skip bodies of library functions.


-subfile(File, options|modules) process just options or just modules from options file File

This is an unusual option and is meant for front-ends trying to achieve some special effect. There are two forms of the option; one with the second argument equal to options and the other with the second argument equal to modules. In general, indirect files (those ending in .lnt) will contain both options and modules. Sometimes it is important to extract just the options from such a file. One example is if you are attempting to do a unit-check on one particular module. Say your project file is project.lnt. Then you might do project and unit checks using the same indirect file.

lint project.lnt // project check 
lint -subfile( project.lnt, options ) filename // unit check

Note that project.lnt may itself have indirect files and that modules and options may be interspersed. The rule is that every indirect file is followed for as long as it takes until the first module is encountered. Every option thereafter is considered not a general option but specific to project check out.

With modules as the second argument to subfile, the processing picks up at precisely the point that the ’options’ subargument left off. Thus if you wanted to place a particular option, say -e1706, just before the first module of project.lnt you could achieve that effect by placing the following in either an indirect file or on the command line:

-subfile( project.lnt, options ) -e1706 
-subfile( project.lnt, modules )


-unit_check unit checkout

This is one of the more frequently used options. It is used when linting a subset (frequently just one) of the modules comprising a program and suppresses Global Wrapup and the messages that would be issued during global wrapup analysis. For historical reasons, -u is an alias for this option.


–unit_check unit checkout and ignore modules in lower .lnt files

This option is like -unit_check except that any module at a lower .lnt level is ignored. Suppose, for example, that project.lnt is a project file containing both options and module names. Then the command line:

lint --unit_check project.lnt alpha.cpp

will do a unit check on module alpha.cpp. It will ignore any module names that may be identified within project.lnt. project.lnt does not have to immediately follow the –unit_check option. Any .lnt file within project.lnt will similarly be processed for options but module names will be ignored. See also -subfile() which deals with this issue in a more comprehensive manner.

For historical reasons, –u is an alias for this option.


-write_file(String, Filename [,append=true|false] [,binary=true|false]) write String to file Filename

The -write_file option is used to write data to a file. The option accepts a string to write and the name of the file to write the contents of the string to. Backslash escapes appearing in the string are converted as expected. By default, the output file is overwritten, to append data to the end of the file, use the sub-option append=true. The sub-option binary can be used to write the data in binary mode.

For example, to append a line containing the text "Starting Lint version X" where X is the major version number to a file named "/home/pclint/lint.log", the below is used:

-write_file("Starting Lint version %LINT_VERSION%\n", 
    "/home/pclint/lint.log", append=true)


-zero | -zero(#) sets exit code to 0

This is useful to prohibit the premature termination of make files.

-zero(#) will set the exit code to zero if all reported errors are numbered # or higher after subtracting off 1000 if necessary. More precisely, messages that have a message number whose modulus 1000 is equal to or greater than #, do not increment the error count reported by the exit code. Note that suppressed errors also have no effect on the exit code. Use this option if you want to see warnings but proceed anyway. This option has no effect if the frz flag is ON.


+zero_err(# [#...]) specify message numbers that should not increment exit code
-zero_err(# [#...]) specify message numbers that should increment exit code

These options allow fine-grained control over exactly which messages contribute to the return value. Additionally, the -exitcode option allows the return value to be explicitly and unconditionally set.

When the frz is OFF, the return value from PC-lint is the number of messages emitted. The +zero_err option can be used to remove message numbers from this set and -zero_err can be used to add messages from this set. For example,

+zero_err(*) 
-zero_err(w1) 
-zero(80??)

will cause the exit code to be set to the number of error messages plus the number of messages issued in the 8000 -8099 range. This option has no effect if the frz flag is ON.


4.6.3 Output

-env_pop pop the current option environment
-env_push push the current option environment
-env_restore(Name) restore the option environment to a previously saved one
-env_save(Name) save the current option environment with name Name

These options can be used to save and recall option environments. These options are similar to -save and -restore but operate in a larger context. Whereas -save and -restore operate only on the base suppression set state (affected by -e# , +e# , -w# , and +efreeze /-efreeze ), these (-env_*) options also affect parameterized suppressions (-esym , -efunc , -estring , etc.) as well as many other options, namely: formatting options, flag options, include directory options, append options, deprecate options, library options, and reserved word options. The option environment manipulated by these options does not include: strong type options, message group options, return value options, function semantic options, or pre-compiled header options. The options -skip_function, -unit_check, and -subfile are similarly not part of the option environment and not affected by these options.

The -env_push and -env_pop options are analogous to -save and -restore . The -env_push option saves the current state of the option environment and a corresponding -env_pop option restores that state. -env_push options can be nested.

The -env_save(Name) option stores away a snapshot of the current option environment and associates it with a Name that can be used to later recall the option environment with -env_restore(Name). The Name may consist of letters, numbers, and the underscore and is case-sensitive.

Attempting to use -env_pop without first using -env_push or specifying a name for -env_restore that was not provided as a name to -env_save will result in error 72 (bad option).


-oe(Filename) redirect stderr to Filename overwriting existing content
+oe(Filename) redirect stderr to Filename in append mode

This is primarily used to capture the help screen. For example:

lint -oe(temp) +si4 ?  

dumps the help information to file temp after the size setting has been made. If the option is introduced with a ’+’ as in +oe(temp) output is appended to the named file.


-os(Filename) redirect stdout to Filename overwriting existing content
+os(Filename) redirect stdout to Filename in append mode

Causes output directed to standard out to be place in the file Filename. This is like redirection and has the following advantages: (a) the option can be placed in a.lnt file or anywhere that a lint option can be placed (b) not all systems support redirection and (c) redirection can have strange side effects. If +os is used rather than -os, output is appended to the file. Make sure this option is placed before the file being linted. Thus

lint -os(file.out) fil.c      

is correct. But

lint fil.c -os(file.out)      

loses the intended output. The reason is that the redirection doesn’t start until the option is encountered.


-stack(&file=filename, &overhead(n), &external(n), &off, name(n), &prealloc_vars) set stack reporting options
+stack enable stack reporting

The +stack version of this option can be used to trigger a stack usage report. The -stack version is used only to establish a set of options to be employed should a +stack option be given. To prevent surprises if a -stack option is given without arguments it is taken as equivalent to a +stack option. See Section 17.6 Stack Usage Report for more details and complete listing of the sub-options.


4.7 Special Detection Options

4.7.1 Metrics

+metric(expr [,options] ) create, check, or nominate a metric
+metric_report([all|nominated]) enable metric report

See Chapter 10 Metrics for details.


4.7.2 Thread Analysis

-locker_tag(type=name [,type=name...]) specify alternate locker tag class names

The standard C++ classes std::adopt_lock_t, std::defer_lock_t, and std::try_to_lock_t are used to specify the lock strategy when constructing a locker class object such as std::shared_lock. The -locker_tag option can be used to specify additional locker tag classes with the same semantics as one of the standard classes which may be useful when configuring thread analysis support for alternate thread libraries.

The option takes one or more arguments of the form type=name where type is one of adopt, defer, or try_to (specifying lock adoption, deferred locking, and try-lock semantics, respectively) and name is the fully qualified name of a class. The specified class will be endowed with lock strategy semantics specified by type when used with a function with the mutex_tag_adopt, mutex_tag_defer, or mutext_tag_try_to_lock semantics (see Supporting Other Thread Libraries ).


-mutex_attr([type, ] value [, mask]) specify shared/recursive values used for pthread_mutexattr_settype

This option is used to specify the values that indicate recursive or shared mutexes when used as an argument to a function with the mutex_attribute_set function semantic which also has a mutex_is_recursive or mutex_is_shared argument semantic (see Supporting Other Thread Libraries ).

By default, only the pthread_mutexattr_settype function has the mutex_attribute_set function semantic with its second argument having the mutex_is_recursive semantic but the -sem option can be used to apply these semantics to other functions. PC-lint Plus will attempt to extract the values indicating a recursive mutex from the macros PTHREAD_RECURSIVE_MUTEX_INITIALIZER or PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP. This option can be used to specify additional values indicating a recursive mutex as well as values that indicate a shared mutex for libraries that support it.

If the first argument to -mutex_attr is shared or recursive, this specifies the type of mutex attribute, otherwise recursive is assumed. The next two arguments specify an integral value and mask with the mask defaulting to -1 if not specified. The argument to a mutex_attribute_set function that corresponds to a mutex_is_recursive or mutex_is_shared parameter indicates a mutex attribute of type when the argument value bitwise anded with mask yields value.

The value and mask arguments may be specified in decimal, octal (by prefixing the number with a 0) or hexadecimal (by prefixing the number with 0x or 0X). Multiple -mutex_attr options may be used to specify multiple value/mask combinations.


-mutex_init(type=name [,type=name...]) specify alternate pthread mutex initialization macro names

By default, PC-lint Plus recognizes the following macros and the recursive / shared semantics implied when used to initialize pthread_mutex_t and pthread_rwlock_t objects:

  • PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP

  • PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP

  • PTHREAD_MUTEX_INITIALIZER

  • PTHREAD_RECURSIVE_MUTEX_INITIALIZER

  • PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

  • PTHREAD_RWLOCK_INITIALIZER

This option is used to specify the properties associated with additional macro names used to initialize statically allocated pthread_mutex_t and pthread_rwlock_t objects.

The option accepts one or more arguments of the form type =name where name is the name of the macro to be registered and type is one of plain, recursive, shared, or both indicating that the specified macro initializes a plain, recursive, shared, or shared and recursive object, respectively.


-thread_report(type=type, file=filename [,format=format] [,filter...] [,field...]) enable a thread analysis report

The -thread_report option is used to trigger a thread analysis report which includes information about the use of threads, functions, variables, and/or mutexes used in a multi-threaded program. See Thread Analysis Reports for more details about the information included in the report and the available sub-options.


4.7.3 Strong Type

-father(parent, child [,child...]) a stricter version of -parent

This option is like the -parent() option except that it makes the relationship a strict one such that a child type can be assigned to a parent type but not conversely. To make all relationships strict you may use the -fhd option. (Turn off the Hierarchy Down flag). If a -parent() option and a -father() option are both given between the same two types then the relationship is considered strict. See Section 7.5.4 Restricting Down Assignments (-father)


-index(flags, ixtype, sitype [,sitype...]) establish ixtype as index type

This option is supplementary to and can be used in conjunction with the -strong option. It specifies that ixtype is the exclusive index type to be used with arrays of (or pointers to) the Strongly Indexed type sitype (or sitype’s if more than one is provided). Both the ixtype and the sitype are assumed to be names of types subsequently defined by a typedef declaration. See Section 7.3 Strong Types for Array Indices


-parent(parent, child [,child...]) augment strong type hierarchy

This option adds a link or links to the strong type hierarchy. See Section 7.5.3 Adding to the Natural Hierarchy


-strong(flags [,name...]) imbues typedefs with strong type checking characteristics

Identifies each name as a strong type with properties specified by flags. Presumably there is a later typedef defining any such name to be a type. Strong types are completely described in Chapter 7 Strong Types .


4.7.4 Miscellaneous Detection

-deprecate(Category, Name [,Commentary]) deprecates the use of Name within Category

The -deprecate option can be used to mark variables, macros, functions, keywords, types, options, and conversion specifiers as deprecated. When a deprecated entity is used in source code, message 586 will be issued warning of the use of a deprecated entity. See 17.8 Deprecation of Entities for more information.


-idlen(count [,options]) specifies the number of meaningful characters in identifier names

This option defines the number of significant characters for different types of identifiers, as well as whether those names should be treated as case-sensitive, for the purpose of reporting name clashes in C modules. When this option is used with a value of count greater than zero, PC-lint Plus will report on pairs of identifiers in the same name space that are identical in their first count characters but otherwise different. Options are:



Option

Meaning



x

eXternal symbols

p

Preprocessor symbols

c

Compiler symbols



If omitted, all symbols are assumed. Uppercase versions of these options may be used to additionally specify that symbol names are case insensitive.

The C language Standards define minimum limits on the number of significant characters of an identifier. Compilers or linkers that employ such a limit will ignore all but the first count characters. The -idlen option can be used to find pairs of identifiers that are identical in the first count characters but are nonetheless different. PC-lint Plus treats the identifiers as different but reports on the clash.

The minimum identifier limits defined by C and the corresponding -idlen values are show below.






Language Version

External
Identifier
Minimum

Internal
Identifier
Minimum

Preprocessor
Identifier
Minimum

PC-lint Plus
options






C89

6 case-insensitive characters

31 case-sensitive characters

31 case-sensitive characters

-idlen(6,X) -idlen(31,pc)

C99

31 case-sensitive characters

63 case-sensitive characters

63 case-sensitive characters

-idlen(31,x) -idlen(63,pc)

C11

31 case-sensitive characters

63 case-sensitive characters

63 case-sensitive characters

-idlen(31,x) -idlen(63,pc)






Option x, external symbols, refers to functions and variables with external linkage. Option p, preprocessor symbols, refers to macros and parameters of function-like macros. Option c, compiler symbols, refers to all the other symbols and includes symbols local to a function, struct/ union tags and member names, enum constants, etc.

Message 621 is issued when two external identifiers clash (across the entire program, regardless of scope), when two compiler identifiers or a compiler and an external identifier clash in the same name space, or when preprocessor identifiers clash. The description of message 621 lists all of the different cases where clashes are reported.

Message 621 may be suppressed for individual identifiers or types of clashes using the -estring option. -idlen is off (equivalent to -idlen(0)) by default.


+misra_interpret(Language*Year, interpretation) enable MISRA interpretation
-misra_interpret(Language*Year, interpretation) disable MISRA interpretation

These options allow for the interpretation of MISRA standards to be configured. The first argument is the language and year of a MISRA standard, one of c2012, c++2008, c2004, or any. Note that only the combinations listed below are allowed. In particular, any may only be used with the interpretations that specify it below and in those cases any must be used.

The second argument is a string which determines which interpretation is modified. These strings are descriptions of the behavior that will change. There are no shorter variants or abbreviations. Ensure you follow any necessary documentation process for your project when modifying the interpretation of MISRA rules.

The configurable interpretations are:

  • any
    return can replace break in switch
    (default OFF)
    When enabled, messages 9042 , 9077 , and 9090 will not be issued for switch cases that are terminated by an unconditional return statement instead of the unconditional break (or throw) statement that is otherwise required.

  • any
    goto can replace break in switch
    (default OFF)
    When enabled, messages 9042 , 9077 , and 9090 will not be issued for switch cases that are terminated by an unconditional goto statement instead of the unconditional break (or throw) statement that is otherwise required.

  • any
    strict identifier uniqueness
    (default OFF)
    When enabled, messages 9103 , 9275 , 9276 , 9277 , 9278 , and 9279 will be issued for enum constants, template type parameters, non-type template parameters, and function parameters.

  • c2012
    essential type differs from standard type only for int and unsigned int
    (default ON)
    When enabled, the essential type of an expression will simply be the standard type of the expression unless the standard type of the expression is (signed) int or unsigned int. Otherwise, such restrictions will only apply when specifically called out by normative text. For example, the essential type of 5UL * 5UL will be unsigned long when this is ON and unsigned char when it is OFF.

  • c2012
    essential type of sizeof is the UTLR of the result
    (default OFF)
    When enabled, the essential type of sizeof and _Alignof expressions that yield constant values will be the unsigned type of lowest rank for the value.

  • c++2008
    underlying type of explicit cast is the cast type
    (default ON)
    When enabled, the underlying type of an explicit cast will be the type that the subexpression was cast to even when the entire expression is an integer constant expression. Otherwise, the entire expression, including the explicit cast, will be assigned an underlying type based on the resulting constant value.

  • c++2008
    permit unmodified non-const incomplete array parameters
    (default OFF)
    MISRA C++ requires that variables be declared using the const qualifier unless they are modified. MISRA C++ also requires that a pointer parameter to which array indexing is applied be declared using array syntax. It not possible to declare a const pointer parameter using array syntax. When enabled, this impossible combination of requirements is relaxed by permitting the lack of const on a parameter of pointer type that was declared as an incomplete (unsized) array. This does not affect constant size array parameters—consider using a reference to an array of constant size instead.

  • c++2008
    ignore constant expression underlying type rules for const variables
    (default OFF)
    When enabled, the MISRA C++ rules specifying the underlying type of an integer constant expression will be ignored when determining the underlying type of an access of an integer constant defined as a const or constexpr variable. This also extends to a unary operator whose operand meets these criteria, and to a binary or ternary operator where either the left/right (or true/false) operands both meet these criteria, or one of them meets these criteria and the other is an integer constant expression.

  • c2004
    allow types of equal size for rule 10.1
    (default ON)
    When enabled, violations of rule 10.1 will not be reported for "conversions" between identical but distinct integer types (for example, int and long could potentially be the same size). Note that even if this is disabled, the word "wider" in rule 10.1 (a) specifically will be interpreted as "not smaller" as required for the rule’s own examples.


4.7.5 Semantic

-function(Function0 [,Function1] [,Function2...]) copy or remove semantics from Function0

This option specifies that Function1, Function2... are like Function0 in that they exhibit special properties normally associated with Function0. The special functions with built-in meaning are described in Section 9.1 Function Mimicry (-function) . See also -sem in Section 9.2 Semantics Specifications .


-printf(N, name1 [,name2...]) specified names are printf-like functions with format provided in the Nth argument

This option specifies that name1, name2, etc. are functions that take printf-like formats. The format is provided in the Nth argument. For example, lint is preconfigured as if the following options were given:

-printf( 1, printf ) 
-printf( 2, sprintf, fprintf )

For such functions, the types and sizes of arguments starting with the variant portion of the argument list are expected to agree in size and type specified by the format. The variant portion of the argument list begins where the ellipsis is given in the function declaration. For non-variadic functions, the first data argument is expected to appear after the format argument. See also -scanf below and Sections 9.1 Function Mimicry (-function) and 17.1 Format Checking . Note that the GCC attribute syntax can also be used to apply the printf semantic when declaring a similar function, see the documentation of the fca flag for more information.


-scanf(N, name1 [,name2...]) specified names are scanf-like functions with format provided in the Nth argument

This option specifies that name1, name2, etc. are functions that take scanf-like formats. The format is provided in the Nth argument. For example, lint is preconfigured as if the following options were given:

-scanf( 1, scanf ) 
-scanf( 2, sscanf, fscanf )

For such functions, the types and sizes of arguments following the Nth argument are expected to be pointers to arguments that agree in size and type with the format specification. See also -printf above. Like -printf the GCC attribute syntax can apply the scanf semantic when declaring a similar function, see the documentation of the fca flag for more information.


-sem(Function [,Sem...]) associates the semantic Sem with Function

This option allows the user to endow his functions with user-defined semantics, or modify the pre-defined semantics of built-in functions. For example, the library function memcpy(a1,a2,n) is pre-defined to have the following semantic checking. The third argument is checked to see that it does not exceed the size (in bytes) of the first or second argument. Also, the first and second arguments are checked to make sure they are not NULL.

To represent this semantic you could have used the option:

-sem( memcpy, 1P >= 3n && 2P >= 3n, 1p, 2p)    

The details of semantic specifications are contained in Section 9.2 Semantic Specifications .


4.7.6 Value Tracking

-specific_climit maximum number of specific calls per function

The total number of specific calls recorded for any one function is limited to n. Because of recursion, the total number of specific calls made on any one function can be huge. This option prevents any one function from hogging resources. By default, the value is 0, implying no limit.


-vt_depth=n specifies the maximum number of nested specific walks

The maximum call stack depth for specific walks during value tracking. This limits the number of nested specific walks and also acts as an upward limit on recursion depth. The default value for this option is 1.


-vt_passes=n specifies the number of passes for intermodule value tracking

The number of times the entire set of project modules will be rescanned to perform additional intermodule value tracking using specific calls saved from the previous pass. Each module is processed during the initial pass where intramodule messages are issued and again during global wrap-up (if it has not been disabled), and each of these constitute a pass. This option can be used to request additional auxiliary passes beyond those that arise naturally from the processing architecture.


4.8 Meta Characters for Options

The following meta characters may be used within names that are used as arguments for options such as: -esym, -efile, -emacro, -efunc, -estring, -etype, -ecall, -libdir, -libh, -libm and the versions of these options that begin with +.

    * wild card character matching 0 or more characters
    ? wild card character matching any single character
    ` backtick used to escape any meta character
    [...] bracketed string meaning optional matches
    "..." used when incorporating comma (,) or unbalanced ’(’ or ’)’ with an argument

Although an option containing meta characters may not always be placed on a command line because the special characters may trip up the shell (command interpreter), it can be placed in a .lnt file.

Arguments (both error numbers and symbols) may contain ’Wild-card’ characters.

For example

-esym( 715, un_* )    

suppresses message 715 for any symbol whose first three characters are "un_". As another example:

-esym( 512, ?, *::* )  

suppresses message 512 for any symbol name containing exactly one character and for any name containing a "::", i.e. for any member name. As another example:

-esym( *, name )      

suppresses any message about symbol name.

A string of the form [...] means that the string bounded by square brackets is optional. E.g.

-esym( 768, [A::]alpha )      

will suppress message 768 for symbols "alpha" and "A::alpha". Wild-card characters may appear within the brackets. Thus

-esym( 768, [*::]alpha )      

will suppress 768 for any symbol where name is "alpha" no matter how deeply nested within classes and or namespaces it may be. The accent grave character ` is sometimes referred to as the backtick. It can be used to escape any of the meta characters. For example

-esym( 1533, operator* )      

suppresses Warning 1533 for any function whose name begins with "operator". However

-esym( 1533, operator`* )      

suppresses 1533 for the function named operator*.

Within options, commas separate arguments. But suppose your argument contains a comma. For this you may use the double-quote. Example,

//lint -etype(1502, "B<float, int>") 
// Without the double quotes, -esym() sees three arguments: 
// "1502", "B<float", and "int>" 
template <class T, class U> class B { }; 
B<float, int> b;

Both wildcard characters and non-wildcard characters may be used both within and outside of the double-quoted sequence. A right parenthesis or comma that appears outside of a double-quoted sequence marks the end of the argument as usual.

The character literals ", `, *, ?, [, and ] may be expressed by escaping them with a backtick:

    `" `` `* `? `[ `]

As a special case, the string "[]" (as in "operator[]" or "extern int a[];") need not be escaped since, as a wildcard pattern, it is meaningless.

All escape sequences other than those mentioned above are reserved for future use. Currently, when we encounter such a sequence, we will ignore the backtick and issue a warning. For example, "`a" is taken as "a".

As a special exception, a pattern that consists entirely of ? and/or * characters is treated as if the pattern were replaced by *. This means, for example, that -e?, -e??, -e???, and -e???? are all equivalent to -e* which disables all messages, i.e. -e? does not disable only messages in the range 1-9.

The patterns supplied to +libdir/-libdir, +libh/-libh, +libm/-libm, and -efile/+efile are matched against files or directories and the following additional properties apply to those patterns:

1.
If the fff flag is enabled, the match will be performed in a case-insensitive manner.
2.
Forward slashes and backward slashes are interchangeable, e.g. a backward slash in a the pattern will match a forward slash in the file or directory being matched.

4.9 How Suppression Options are Applied

PC-lint Plus has a rich set of options that govern when and how diagnostics are issued. It is possible for multiple options to affect the issuance of a particular diagnostic. This section describes the process by which PC-lint makes the determination to issue a specific diagnostic, including the interaction of multiple relevant suppression options.

Note that the term "suppression options" is used here to refer both to options that suppress a message (e.g. -e#) and options that enable a message (e.g. +esym).

PC-lint Plus performs the following steps, in the order given, to determine if the message should be suppressed or issued.

1.
If the message is an unsuppressible message (errors 305, 309, 315, 330, and 367), the message is issued.
2.
If a single-line suppression exists on the same line as the location given in the message, and the message is not frozen (with the +efreeze or ++efreeze options) at the point of the suppression, the message is suppressed.
3.
If the location of the message is subject to a scoped suppression (-e(#), –e(#), -e#, or –e#, including those resulting from -emacro((#)), etc. options), and the message is not frozen at the point of suppression, the message is suppressed.
4.
A voting mechanism is next employed to determine whether to issue the message. If the message is currently in the set of enabled messages (this is the message set that is manipulated by the -w /-e /+e options), one vote is cast in favor of issuing the message. Each -esym , -etype , -estring , -equery , -egrep , -efile , -ecall , -efunc , -elibcall , -elibsym , -elibmacro , and -emacro option that applies to the current message casts its votes in favor of suppressing the message for each parameter in the message that is matched by the option. Similarly, each applicable +esym , +etype , +estring , +egrep , +equery , +efile , +emacro , +ecall , +efunc , and +elibcall option casts its votes in favor of emitting the message. If the number of votes to suppress is greater than or equal to the number of votes to issue the message, the message is suppressed.
5.
If the message location refers to a library region, and the message is suppressed for libraries via the -elib or -wlib options, the message is suppressed.
6.
The message is issued.

Parameterized suppression options cast one vote for each parameter in the message that matches the provided pattern.
Global wrap-up messages targeting symbols that were ever declared in a non-library region are treated as non-library regardless of the location used to issue the message unless the flo flag is active. Library suppressions are not applied to such messages.

Example

Elective Note 9001 (octal constant ’String’ used) is parameterized by a single string (the octal constant encountered). Given a file example.c that contains:

int i1 = 00; 
int i2 = 01;

If PC-lint Plus is run with the options -w1 +e9001 (disabling all non-error messages and then enabling note 9001), the messages issued are:

note 9001: octal constant '00' used 
note 9001: octal constant '01' used

The +e9001 results in one vote in favor of issuing the messages and nothing casts a vote against. If we add the option -efile(9001, example.c), both messages will be suppressed because for each message the +e9001 effects one vote in favor of issuing and the -efile option votes against issuing the note. Since there are not more votes to issue than to suppress, the message is suppressed. If we also add the option +estring(9001, 00) an extra vote will be cast to issue the message when the message references the octal constant 00 resulting in the output:

note 9001: octal constant '00' used

In other words, when using the options +e9001 -efile(9001, example.c) +estring(9001, 00), message 9001 will be allowed in all files except example.c where only uses of the octal constant 00 will be reported.

4.10 Rules for Parameterized Suppressions

The parameterized suppression options are:

    -esym , -etype , -estring , -equery , -egrep , -efile , -ecall , -efunc , -emacro ,
    +esym , +etype , +estring , +equery , +egrep , +efile , +ecall , +efunc , and +emacro .

A parameterized suppression option is ignored if an identical option is already in effect in the current option environment. For example, the options -esym(714,foo) -esym(714,foo) cannot be used to cause two votes against message 714 when issued for symbol foo as the second identical option will be ignored.

Two parameterized suppression options of the same kind are considered to be identical if they specify equivalent effective message sets and identical parameter patterns. The effective message set for parameterized message disabling options (those starting with "-") is the specified message set minus any messages that are currently frozen via +efreeze/++efreeze options. For parameterized message enabling options (those starting with "+"), the effective message set is always the same as the specified message set. Two parameter patterns are considered identical only if their spelling is identical.

This means, for example, that -esym(71?,foo) is considered identical to -esym(710 711 712 713 714 715 716 717 718 719,"foo") (assuming that no messages in the range 710-719 are frozen) as both options have equivalent effective message sets (710-719) and identical parameter patterns (foo, argument delimiting quotes are not considered to be part of the spelling).

If message 714 was frozen when the first -esym(71?,foo) option was seen, the same option appearing when 714 was no longer frozen would be not be ignored because the effective message sets of the two options are different.

The option -esym(714,"[f]oo") is distinct from -esym(714,"foo") because the parameter patterns are not identical and both options will cast a vote against issaunce of message 714 for a symbol foo.

A "-" version and a "+" version of a paramterized message suppression option with identical arguments may exist at the same time with each being able to cast a vote at message issuance time. This distinction is relevant in the following example:

//lint -esym(714,foo) 
   ... // region A 
//lint +esym(714,foo) 
 
//lint -esym(714,foo) 
   ... // region B 
//lint +esym(714,foo)

The intent was to suppress message 714 for symbol foo only within regions A and B. The effect is obtained for region A since the first -esym option will cast a vote against the message and the first +esym will effectively negate the first -esym by casting a vote for the message. Since both options remain in effect and, as previously stated, later identical parameterized suppressions are ignored, the second -esym option will have no effect and message 714 will not be suppressed within region B (the first -esym will cast one vote against issuance which will be canceled out by the first +esym casting a vote for issuance). The desired effect can be obtained through the use of temporary option environments using -env_push and -env_pop :

//lint -env_push -esym(714,foo) 
   ... // region A 
//lint -env_pop 
 
//lint -env_push -esym(714,foo) 
   ... // region B 
//lint -env_pop

4.11 Flag Options

Options beginning with +f, ++f, -f, or –f introduce flags. A flag is represented internally by an integer and is considered

    ON if the integer > 0
    OFF if the integer <= 0

Default settings are either 1 if ON or 0 if OFF.

    +f... turns a flag ON by setting the flag to 1.
    -f... turns a flag OFF by setting the flag to 0.
    ++f... increments the flag by 1.
    –f... decrements the flag by 1.

The latter two operations are useful in cases where you may want to turn a flag ON locally without disturbing its global setting. For example:

/*lint  ++flb  */ 
int printf(); 
/*lint  --flb  */

can be used to set the flb (library) flag ON for just the one declaration and, afterward, restoring the value of the flag to whatever it had been.

The table below summarizes the available flag options. Flags that were introduced in PC-lint 9 or earlier are marked — in the version column.





f12

OFF

view MISRA C 2012 essential types

1.0





f@m

OFF

commerical ’@’ is a modifier





faa

OFF

enable aligned allocations

2.1





fac

OFF

allow instantiation of abstract classes

1.0





faf

OFF

enable tracking of all function call locations for thread reports

1.4





fai

ON

arguments pointed to get initialized





fan

OFF

support anonymous unions





fas

OFF

support anonymous structs





fat

ON

parse .net attributes





fau

OFF

bitwise AND with negative constant is unknown

1.2





fav

OFF

enable tracking of all variable access locations for thread reports

1.4





fba

OFF

bit addressability





fbe

OFF

enable backslash escapes for special option characters

1.1





fbl

OFF

dependent base class lookup in templates

1.0





fbo

ON

activate bool, true, false





fca

ON

convert attributes to semantics

1.0





fcc

OFF

capitalize message categories

1.0





fce

OFF

continue on #error





fcm

ON

copy semantics from macro definitions

1.0





fcn

ON

convert non-printable characters in context line

1.0





fcp

OFF

all subsequent modules are considered C++ 





fcs

OFF

continue on static assertion failure

1.0





fcu

OFF

char is unsigned





fcv

ON

don’t report parameter could be const if exclusively cast to void

1.3





fcw

ON

attribute responsibility for last write in callee to caller

1.2





fdd

ON

dimensional by default





fde

OFF

initialization with explicitly declared default constructor is explicit

1.3.5





fdg

ON

expansion of digraphs





fdh

OFF

append ’.h’ to header names in #include’s





fdi

ON

search directory of including file





fdl

OFF

pointer difference is long





fdm

OFF

comma from macro expansion does not delimit macro args

1.0





fdt

OFF

delayed template parsing

1.0





fdx

OFF

consider use of operator delete to be a modification

1.0





fec

OFF

allow colon introducer for explicit address extension

2025





fee

ON

expand environment variables

1.0





fei

OFF

underlying type for enum is always int





fes

OFF

search enclosing scopes for friend tag decls

1.0





fet

OFF

require explicit throw specifications





ffb

ON

for loop creates separate block





ffc

ON

non-library functions assume custody of non-const pointers





fff

ON

fold filenames to a consistent case





ffi

OFF

format integers relative to nearby limits

1.3





ffj

ON

join within one-way hierarchy yields base

1.4





ffn

OFF

use full file names





ffv

OFF

implicit function to void pointer conversion

1.0





ffw

OFF

allow friend decl to act as forward decl

1.0





fgi

OFF

inline treated as GNU inline

1.0





fgl

ON

use GNU line markers in preprocessed output

1.2





fhd

ON

allow hierarchy downcasts





fho

OFF

header include guard optimization

1.0





fhs

ON

natural hierarchy of strong types





fhx

ON

hierarchy of index types





fia

OFF

inhibit supplementary messages

1.0





fie

OFF

use the integer model for enums





fim

ON

-i can have multiple directories





fin

OFF

refer to supplemental messages with the info label

1.0





fit

OFF

thrown exception renders function not declared noexcept impure

2.0





fiw

ON

initialization is a write





fiz

ON

initialization by zero is a write





fkp

OFF

use K&R preprocessor





fla

ON

locations for all diagnostics

1.0





flb

OFF

treat code as library





flf

OFF

process library functions





fll

OFF

allow long long int





flm

OFF

lock message format





fln

ON

honor #line directives for diagnostics





flo

OFF

library declarations override non-library declarations

1.4





flp

OFF

lax null pointer constants

1.0





fls

OFF

assume external call chains modify static local variables

1.3.5





fma

OFF

microsoft inline asm blocks

1.0





fme

ON

enable metrics

2.0





fmi

OFF

enable supplemental mutex information messages

1.4





fml

OFF

metrics for library entities

2.0





fms

OFF

microsoft semantics

1.0





fmt

OFF

match template template-arguments to compatible templates

1.2





fmx

ON

enable member access control in C++ 

1.2





fnc

OFF

nested comments





fnf

OFF

fall back to operator new when new[] not available

1.0





fnn

OFF

new can return null





fnr

OFF

null pointer return





fnz

ON

null pointers correspond to the integral value zero

1.3.5





fon

ON

support for C++ operator name keywords





fpa

OFF

pause before exiting





fpe

ON

use precision of enumerators instead of explicit enum base type

1.2





fpm

OFF

limit precision to the maximum of the arguments





fpn

OFF

pointer parameter may be null





fpo

ON

limit precision to the type of the operation





fqb

ON

qualifiers go before types





fql

ON

execute queries in library regions

2.1





frc

OFF

remove commas before __VA_ARGS__

1.0





frd

OFF

redefine default params for class template function members

1.0





frz

ON

use return code only to indicate execution failure

1.0





fsc

OFF

strings are const char* even in C





fsd

OFF

output stack diagrams

1.0





fse

OFF

use smallest underlying type for enums

1.0





fsf

OFF

display function names for semantics during calls

1.0





fsi

OFF

search #include stack

1.0





fsl

OFF

single line comments

1.0





fsn

ON

treat strings as names





fso

OFF

return semantics override deduced return values

1.0





fsp

ON

specific calls





fsv

ON

track static variables





fta

ON

enable typographical ambiguity checks





ftc

ON

enable thread analysis checks

1.4





ftg

ON

permit trigraphs





fub

ON

ignore unreachable break in switch

1.3





fum

OFF

user declared move deletes only corresponding copy

1.0





fun

OFF

issue additional stack usage notes

1.0





fup

OFF

treat null pointer values as unknown after reporting them

1.3





fur

OFF

allow unions to contain reference members

1.0





fuu

OFF

treat uninitialized values as unknown after reporting them

1.3





fuv

OFF

report unreferenced variables that could be const

2025





fvd

OFF

interactive value tracking debugger

1.0





fwu

OFF

wchar_t is unsigned





fxt

OFF

extern C functions can throw exceptions

1.3





fzd

OFF

enable sized deallocations

1.2





fzl

OFF

sizeof is long





fzu

ON

sizeof is unsigned










f12   view MISRA C 2012 essential types (default OFF).

Issues message 9903 after full expressions to illustrate the MISRA C 2012 essential types involved in the expression and how they combine to form new essential types.

For example, given:

int f(int a, short b) { 
   return (b + b) + (a + b); 
}

PC-lint Plus emits:

note 9032: left operand to + is a composite expression of type 
   'signed16' which is smaller than the right operand of type 'signed32' 
   return(b + b) + (a + b); 
         ~~~~~~ ^

Why is the left side signed16 and the right side signed32?

Processing the example with +f12 and +e9903 yields the step by step evaluation of the expression with the corresponding essential types involved at each step:

info 9903: (signed16 + signed16) + (signed32 + signed16) 
info 9903: (signed16) + (signed32) 
info 9903: signed32


f@m   commerical ’@’ is a modifier (default OFF).

This is a feature required by some embedded compilers that employ a syntax such as:

int @interrupt f() { ... }    

the @interrupt serves as a modifier for the function f (to indicate that f is an interrupt handler). Normally ’@’ would not be allowed as a modifier. If the option +f@m is given then ’@’ can be used in the same contexts as other modifiers. There will be a warning message (430 ) but this can be suppressed with a -e430. The ’@’ will otherwise be ignored. The keyword that follows should be identified either as a macro with null value as in -dinterrupt= or as a reserved word using +rw(interrupt).


faa   enable aligned allocations (default OFF).

This flag controls whether the C++17 aligned allocation feature is enabled.

Enabling this flag will allow for the recognition of operator new and delete global replacement functions. This may solve some parse errors related to aligned allocations when the feature is in use.


fac   allow instantiation of abstract classes (default OFF).

Some compilers allow instantiation of abstract classes (e.g. Visual C++ 6). If this flag is ON, such instantiations will be allowed, otherwise an error will be emitted and the class will not be instantiated.


faf   enable tracking of all function call locations for thread reports (default OFF).

If this flag is ON, all function call locations will be emitted in the thread analysis function report (see Function Reports ). When this flag is OFF, only the first location of each called function with a unique mutex lock ordering is reported. Setting this flag enables collection of the additional information required to report all calls.


fai   arguments pointed to get initialized (default ON).

When an argument is passed to a function in the form of a pointer or reference to an uninitialized object and the receiving parameter is a pointer or reference to non-const, it is assumed by default that the object will be initialized to an unknown value. Thus, in the following:

void f(int*); 
int g() { 
   int x; 
   f(&x); 
   return x; // OK, no warning. 
}

we do not warn of the possibility that x is uninitialized due to the presumed initialization afforded by the function f. However, if the flag is turned OFF (using -fai), then we will warn when x is read in the return statement. If the function f is intended to accept and modify a previously initialized value, then the inout semantic can be applied to the parameter. Use of an uninitialized value would then be reported only at the call to f regardless of the flag state. See Section 9.2.1 Possible Semantics .


fan   support anonymous unions (default OFF).

If this flag is ON, anonymous unions are supported in C90 and C99 modes (they were added to the language in C11). Anonymous unions appear within structures and have no name within the structure so that they must be accessed using an abbreviated notation. For example:

struct abc { 
   int n; 
   union { int ui; float uf; }; 
} s;

In this way a reference to one of the union members (s.ui or s.uf) is made as simply as a reference to a member of the structure (s.n).


fas   support anonymous structs (default OFF).

If this flag is ON, anonymous structs are supported in C90 and C99 modes (they were added to the language in C11) as well as in C++. Anonymous structs are similar to anonymous unions. That is, if a struct has no tag and no declarator as in:

struct X { 
   struct { int a; int b; }; 
} x;

then references to the members of the inner struct are as if they are members of the containing struct. Thus x.a refers to member a within the unnamed struct within struct X.


fat   parse .net attributes (default ON).

Dot net (.net) attributes are contained within square brackets. E.g.

[propget, id(1)] void f( [out] int *p );      

The square brackets and information contained therein are non standard extensions to the C/C++ standards supported by the Microsoft Visual C 7.00 and later compilers. Remarkably this doesn’t appear to interfere (or be ambiguous) with other uses of square brackets within the language. For this reason the flag is normally ON. To turn off such processing use -fat


fau   bitwise AND with negative constant is unknown (default OFF).

If this flag is ON, Value Tracking will treat the result of a bitwise AND operation between an unknown value and constant value as unknown. If it is OFF, the result will be based on the value of the constant and the range of the type of the unknown operand.


fav   enable tracking of all variable access locations for thread reports (default OFF).

If this flag is ON, all accesses to each variable will be emitted in the thread analysis function report (see Function Reports ). When this flag is OFF, only the first location of each variable access with a unique access type and set of owned mutexes is reported. Setting this flag enables collection of the additional information required to report all accesses.


fba   bit addressability (default OFF).

If this flag is ON (by default it is OFF), an individual bit of an int (or any integral) can be specified using the notation:

a.integer-constant      

where a is an expression representing the integral and integer-constantis an integer constant. The construct is treated as a bit field of length 1.

For example, the following code:

/*lint +fba Turn on Bit Addressability */ 
int n; 
n.2 = 1; 
n.4 = 0; 
... 
if( n.2 || n.4 ) ...

will set the 2nd bit of n to 1 and the 4th bit to 0. Later it tests those bits. This syntax is not standard C/C++ but does represent a common convention used by compilers for embedded systems.


fbe   enable backslash escapes for special option characters (default OFF).

When the fbe flag is enabled, the backslash character can be placed immediately before any of the following special characters to remove the special meaning of that character:

{  }  (  )  [  ]  !  ,  "  \

When this flag is enabled, any other character following a backslash inside an option will be met with eror 72 (bad option). The fbe flag can be turned ON and OFF between options.


fbl   dependent base class lookup in templates (default OFF).

When this flag is ON, unqualified lookup in a class template will result in a search of dependent base classes. This is non-standard behavior implemented by some compilers.


fbo   activate bool, true, false (default ON).

If this flag is ON, keywords bool, true, and false are activated at the start of every C++ module.


fca   convert attributes to semantics (default ON).

If this flag is ON, certain attributes appearing in function declarations using the GCC attribute syntax will automatically be converted to function semantics. The supported attribute to semantic mappings are:



format(printf, index, first-to-check)

-printf(index, func)



format(scanf, index, first-to-check)

-scanf(index, func)



noreturn

-sem(func, r_no)



nonnull(i)

-sem(func, iP)



const

-sem(func, pure)



pure

-sem(func, pure)




For example, given the declaration:

extern int 
my_printf (void *my_object, const char *my_format, ...) 
           __attribute__ ((format (printf, 2, 3)));

the effect of the option -printf(2, my_printf) is automatically applied to the function.

Semantics applied from attributes only affect the overload in which the attribute appears.


fcc   capitalize message categories (default OFF).

In PC-lint, the message categories (Error, Warning, Info and Note) were spelled with an initial uppercase letter. In PC-lint Plus, these categories are presented in all lower case. Setting this flag will emulate the PC-lint 9 behavior. If the value of the flag is 2 or greater (using ++fcc, the message categories will be presented in all upper case (ERROR, WARNING, etc).


fce   continue on #error (default OFF).

PC-lint Plus will normally terminate with a fatal error (309 ) when a #error preprocessing directive is encountered. If this flag is set to a value of 2 or greater, PC-lint Plus will still emit the error message but continue processing. This may be useful to help troubleshoot incomplete configurations in a handful of circumstances but this option should never be employed in a production environment because its use will only serve to hide serious configuration issues.

When PC-lint Plus is forced to continue processing after encountering such an error, the generated AST may be incorrect/incomplete and resulting analysis can no longer be considered to be reliable. Because of this, message 686 will be issued when this option is used. Additionally, note that while processing will continue when using this option, message 309 is still emitted and cannot be suppressed. Message 309 typically indicates missing macro definitions and can usually be resolved by examining the context in which the error is emanating and defining the appropriate macro(s).


fcm   copy semantics from macro definitions (default ON).

This flag controls when function semantics are copied from one function to another due to a macro definition. For example, if the following macro definition is encountered:

#define malloc xmalloc  

calls to malloc would be changed to calls to xmalloc but the built-in function semantics for the malloc function would not be copied to xmalloc. The same issue exists for functions with user-defined function semantics.

When this flag is ON (default), semantics are copied only if the name of the new function is the same as the old function with optional underscores at the beginning and/or end of the new name and message 828 will be issued to announce the semantic copying. In all other cases, semantics will not be copied and warning 683 will be issued.

When this flag is OFF (-fcm), semantics are never copied and message 683 will always be issued when a #define is used to define a macro with the same name as a function that has semantics.

If this flag is set to a value of 2 (++fcm), semantics are always copied, producing message 828 each time.

Note that if the new name corresponds to a function that already has semantics associated with it, no copying is performed and no message is issued.


fcn   convert non-printable characters in context line (default ON).

This flag controls how non-printable characters in source code lines are represented in the context line of messages. When this flag is ON, non-printable characters are presented using the syntax <U+dddd > where dddd is the hexadecimal value of the UTF32 version of the character. Note that this conversion only occurs for the context lines included in emitted messages. If the flag is OFF the character is printed as-is, without conversion.

Note: If you are using a message height of 2 (which causes the position indicator to be embedded in the context line), and your position indicator includes non-printable characters (such as ANSI/VT100 terminal escape sequences), you will need to turn this flag OFF to keep those characters from being converted.


fcp   all subsequent modules are considered C++ (default OFF).

When this flag is ON, all subsequent modules will be processed as C++ modules, not just the ones having a distinguished extension (by default ".cpp" and ".cxx").


fcs   continue on static assertion failure (default OFF).

PC-lint Plus will normally terminate with a fatal error (330 ) when a static assertion fails. If this flag is set to a value of 2 or greater, PC-lint Plus will still emit the error message but continue processing. This may be useful to help troubleshoot incomplete configurations in a handful of circumstances but this option should never be employed in a production environment because its use will only serve to hide serious configuration issues.

When PC-lint Plus is forced to continue processing after encountering such an error, the generated AST may be incorrect/incomplete and resulting analysis can no longer be considered to be reliable. Because of this, message 686 will be issued when this option is used. Additionally, note that while processing will continue when using this option, message 330 is still emitted and cannot be suppressed. Message 330 typically indicates missing or incorrect scalar type sizes (which can be configured with the -s option), missing type definitions, or missing or incorrectly specified macros. Review the message details and the context in which the failure occurs to address the underlying cause.


fcu   char is unsigned (default OFF).

If this flag is ON, plain char declarations are assumed to be unsigned. This is useful for compilers that, by default, treat char as unsigned. Note that this treatment is specifically allowed by the ANSI/ISO standard. That is, whether char is unsigned or signed is up to the implementation.


fcv   don’t report parameter could be const if exclusively cast to void (default ON).

When this flag is ON, PC-lint Plus will not report that a parameter could be made const (or pointer to const, etc.) if the only reference to the parameter was a cast to void.


fcw   attribute responsibility for last write in callee to caller (default ON).

If this flag is ON an unread write within a called function may later be reported in the caller with message 438 . If this flag is OFF such writes will not be visible to callers.

For example:

1void f(int* p) { 
2   *p = 10; 
3} 
4 
5void g(void) { 
6   int a; 
7   f(&a); 
8}

will emit 438 when this flag is ON but not when it is OFF:

warning 438: last value assigned to 'a' not used 
} 
^ 
supplemental 891: previous assignment is here 
   *p = 10; 
      ^


fdd   dimensional by default (default ON).

If this flag is ON then strong types (with the ’J’ flag) will be considered equivalent to ’Jd’. The resulting behavior will be equivalent to treating the type as a physical dimension such as meters or seconds. See Section 7.4 Dimensional Analysis .


fde   initialization with explicitly declared default constructor is explicit (default OFF).

When this flag is ON, PC-lint Plus will consider an implicit initialization using an explicitly-declared default constructor to constitute an explicit initialization for the purposes of messages 727 , 728 , and 738 .


fdg   expansion of digraphs (default ON).

By default, PC-lint Plus will expand digraph sequences. If this flag is turned off, digraph sequences will not be expanded.


fdh   append ’.h’ to header names in #include’s (default OFF).

When the Dot-H flag is ON (+fdh) and if an extension-less header is seen, an attempt is made to open the file first with the .h extension and, that failing, open the file using the original name. If the flag has a value of 2 or higher, an attempt is made to open the .h extended name but not on the original name.


fdi   search directory of including file (default ON).

If this flag is ON, the search for #include files will start with the directory of the including file (in the double quote case) rather than with the current directory. This is the standard Unix convention and is also used by the Microsoft compiler. For example:

#include "alpha.h"    

begins the search for file alpha.h in the current directory if the fdi flag is OFF; or in the directory of the file that contains the #include statement if the fdi flag is ON. This normally won’t make any difference unless you are linting a file in some other directory as in:

lint source\alpha.c    

If alpha.c contains the above #include line and if alpha.h also lies in directory source you need to use the +fdi option.


fdl   pointer difference is long (default OFF).

This flag specifies that the difference between two pointers is typed long. Otherwise the difference is typed int. This flag is automatically adjusted upon encountering a typedef for ptrdiff_t.

If the value of the flag is 2, then pointer differences are assumed to be long long. This can occur through the pair of options:

+fdl ++fdl    


fdm   comma from macro expansion does not delimit macro args (default OFF).

When this flag is ON, single commas from nested macro expansions are not treated as argument separators. In PC-lint 9 this behavior was implemented via the option.

+compiler(comma_from_macro_expansion_does_not_delimit_macro_args)      


fdt   delayed template parsing (default OFF).

When this flag is ON, parsing of function template definitions will occur at the end of the module instead of when the definition is initially encountered. This is necessary to properly parse certain constructs that are not technically valid C++ but are allowed (and employed) by some implementations.


fdx   consider use of operator delete to be a modification (default OFF).

When this flag is ON, the application of operator delete will make its argument ineligible for the suggestion that it could be a pointer to const. While it is legal to delete a pointer to const, this can subvert the common expectation that the target of a pointer to const will not be changed.


fec   allow colon introducer for explicit address extension (default OFF).

When this flag is ON, the explicit variable address extension described in the description of message 430 will recognize ‘:’ as an alternative to ‘@’. For example:

int y : 0x2000;

will be interpreted as specifying that the variable y is located at memory address 0x2000 when this flag is ON. This syntax is disabled by default due to its potentially confusing resemblance to a bit-field.


fee   expand environment variables (default ON).

This flag controls how environment variables are handled when appearing in lint options surrounded by percent signs, e.g. %PATH%. If this flag is OFF, environment variables are not expanded. If this flag is set to a value of 1 (the default), environment variables are expanded but not recursively. If this flag is set to a value greater than 1, environment variables are recursively expanded.


fei   underlying type for enum is always int (default OFF).

If this flag is ON, the underlying type of enumerations will always be ’int’. Otherwise, the Standard C/C++ rules will be used for determining the underlying type.


fes   search enclosing scopes for friend tag decls (default OFF).

If this flag is ON, name lookup will consider enclosing scopes for unqualified friend tag declarations that are not template-ids, allowing redeclaration from an enclosing namespace. In Standard C++, only scopes within the innermost enclosing namespace are considered. Note that this lookup scope extension occurs only for types, not functions.


fet   require explicit throw specifications (default OFF).

If the flag is OFF then the absence of an exception specification (the throw list for a function) is treated as a declaration that the function can throw any exception. This is standard C++. If the flag is ON, however, the function is assumed to throw no exception. In effect, the flag says that any exception thrown must be explicitly given. Consider

double sqrt( double x ) throw( overflow ); 
double abs( double x ); 
double f( double x ) 
   { 
   return sqrt( abs(x) ); 
   }

In this example, sqrt() has an exception specification that indicates that it throws only one exception (overflow) and no others. The functions abs() and f(), on the other hand, have no exception specification, and are, therefore, assumed to potentially throw all exceptions. With the Explicit Throw flag OFF you will receive no warning. With the flag ON (with a +fet), you will receive Warning 1550 that exception overflow is not on the throw list of function f().

The advantage of turning this flag ON is that the programmer can obtain better control of his exception specifications and can keep them from propagating too far up the call stack. This style of analysis is very similar to that employed quite successfully by Java.

The disadvantage, however, is that by adding an exception specification you are saying that the function throws no exception other than those listed. If a library function throws an undeclared exception (such as abs() above) you will get the dreaded unexpected() function call. See [?, Item 14], Scott Meyers "More Effective C++".

Can you have the best of both worlds? Through the magic of macros it would appear that you can. For example, you can define a macro Throw as follows:

#ifdef _lint 
   #define Throw( x ) throw(x) 
#else 
   #define Throw( x ) 
#endif

When linting you would turn on the +fet flag. You would then use the Throw macro for all your exception specifications that PC-lint Plus is warning you to add. These specifications will not be seen by the compiler and therefore will not get you into trouble.

Unfortunately, you will soon discover, that Throw doesn’t handle the multiple argument case. Clearly you can define a series of separate macros, Throw2, Throw3, etc. for different argument counts. But you can also define a multiple argument macro Throws as follows:

#define Throws(X) throw X      

Unfortunately, this requires an extra set of parentheses when you use it as in:

Throws((overflow,underflow))  

But this is not necessarily a bad thing since it will alert the reader of the code that these are not seen by the compiler.


ffb   for loop creates separate block (default ON).

The C++ standard designates that variables declared within for clauses are not visible outside the scope of the for loop. For example, in the following code, i cannot be used outside the for loop.

for( int i = 0; i < 10; i++ ) { 
   // ... 
} 
// can't use i here.

Some compilers still adhere to an earlier practice in which variables so declared are placed in the nearest encompassing block.

By default, this flag is ON indicating that the standard is supported. If your compiler follows a prior standard you may want to turn this OFF with the option -ffb.


ffc   non-library functions assume custody of non-const pointers (default ON).

This flag is normally ON. It signifies that all non-library functions will automatically assume custody of a pointer through any non-const pointer parameter. Turning this flag OFF (with a -ffc) will mean that a given function will not take custody of a pointer unless explicitly directed to do so via a custodial semantic for that function and argument.

void f( int * );       // f takes custody 
void g( const int* );   // but g does not 
//lint --ffc             turn the flag off 
void h( int * );       // h will not take custody 
//lint ++ffc             restore the flag

The non_custodial argument semantic can be used to create an exception when this flag is ON. Conversely, the custodial argument semantic can be used to indicate that a function takes custody when it would not be implied by this flag. See option -sem . See also message 429 .


fff   fold filenames to a consistent case (default ON).

If this flag is ON, file names are processed case-insensitively such that X.C may refer to a file with the name x.c, #include "a.h" can be used to include a header with the name A.H, etc. The options +lnt, +cpp, and +ext are also effected, e.g. after +cpp(cc) both ".cc" and ".CC will be considered to be C++ extensions. This flag is only intended for use with case-insensitive filesystems.


ffi   format integers relative to nearby limits (default OFF).

When this flag is ON, Value Tracking messages portraying large integer values and ranges will be formatted relative to nearby signed or unsigned integer type limits. For example 5 + (uint32_t)-1 will be displayed as (UINT32_MAX + 5) and 2147480000 will be displayed as (INT32_MAX - 3647).

Positive values may be compared to signed or unsigned type limits regardless of the signedness of the type of the value’s expression. Negative values will only be displayed relative to a signed integer type minimum. Values may match a limit exactly or be offset in either direction. The offset is limited by the magnitude of the square root of the limit (e.g. a 32-bit limit is restricted to a 16-bit offset). Integers that do not satisfy the criteria for relative formatting will still be printed literally. Each side of a range is considered independently. One, both, or neither could be displayed in relative format depending on the values.


ffj   join within one-way hierarchy yields base (default ON).

If this flag is ON, the non-dimensional result of an additive, multiplicative, or bitwise binary operator whose operand types are within a one-way hierarchy (see -father and -fhd ) will be the base type rather than the derived type. This also applies to the interpretation of compound assignment. For example:

//lint -w1 +e63? 
//lint -strong(AJX, Number, Index) 
//lint -father(Number, Index) 
 
typedef unsigned Number; 
typedef unsigned Index; 
 
void foo(Number number, Index index) { 
   Number x = number + index; 
   x += index; 
   Index y = number + index; 
   y += number; 
}

The initialization and subsequent assignment to y will each trigger messages 632 and 633 when this flag is ON (Number + Index Number) but not when it is OFF (Number + Index Index).


ffn   use full file names (default OFF).

When this flag is ON filenames reported in error messages are full path names. This can assist editors in locating the correct position within files when default directories may be different than during the linting process. If this flag is OFF (default), filenames are reported as provided to PC-lint Plus. If this flag has a negative value (–ffn), the filenames are reported using just the base file name.


ffv   implicit function to void pointer conversion (default OFF).

If this flag is ON, implicit "function pointer" to "void pointer" conversions are allowed in C++ mode (they are always allowed in C mode).


ffw   allow friend decl to act as forward decl (default OFF).

When this flag is ON set, friend declarations act as forward declarations. This is not standard C++ behavior but is supported by some compilers.


fgi   inline treated as GNU inline (default OFF).

When this flag is ON, GNU inline semantics are applied to entities declared with the inline keyword. Namely, declarations with inline that are not declared static are externally visible even if no extern specifier is present. This matches the behavior of GNU90 mode.


fgl   use GNU line markers in preprocessed output (default ON).

If this flag is ON, preprocessed output will employ GNU line marker syntax instead of the standard #line directives.


fhd   allow hierarchy downcasts (default ON).

This flag is ON by default. The strong-Hierarchy-Down flag refers to assignments between strong types related to each other via the strong type hierarchy. Normally you may freely assign up and down the hierarchy without drawing a warning. With this flag set OFF, a warning will be issued whenever you assign down the hierarchy. For example:

typedef int X; 
typedef X Y;

Then an assignment from an object of type X to a variable of type Y will draw a warning if the flag is turned off. See Sections 7.5.4 Restricting Down Assignments (-father) and 7.5.3 Adding to the Natural Hierarchy .


fho   header include guard optimization (default OFF).

This flag controls the handling of header files that utilize include guards. If this flag is ON, header files with valid include guards are not re-processed and as such they will not show up in verbosity messages (with -vi or -va ) and lint options that appear before the include guard or in files included after the include guard will not be executed after the initial inclusion. If the flag is OFF, files will be entered every time they are referenced. Note that in neither case are the contents of the guarded region re-processed, this flag controls only whether or not the file is re-entered before making the decision to re-process. This flag does not affect headers using #pragma once, such files are never re-entered regardless of the value of this flag.


fhs   natural hierarchy of strong types (default ON).

If this flag is ON (it is by default) strong types are considered to form a hierarchy based on typedef statements. See Section 7.5.2 The Natural Type Hierarchy and Section 7.5.3 Adding to the Natural Hierarchy .


fhx   hierarchy of index types (default ON).

If this flag is ON (it is by default) strong index types are related via the type hierarchy. See Chapter 7 Strong Types . See also the +fhs flag.


fia   inhibit supplementary messages (default OFF).

If this flag is ON, supplementary messages (831 and 890-899) will be suppressed.


fie   use the integer model for enums (default OFF).

If this flag is ON, a loose model for enumerations is used (loose model means that enumerations are regarded semantically as integers). By default, a strict model is used wherein a variable of some enumerated type, if it is to be assigned a value, must be assigned a compatible enumerated value and an attempt to use an enumeration as an int is greeted with a (suppressible) warning 641 . An important exception is an enum that has no tag and no variable. Thus

enum {false,true};    

is assumed to define two integer constants and is always integer model.


fim   -i can have multiple directories (default ON).

With this flag ON, the -i option may specify multiple include directories (like the INCLUDE environment variable). For example,

-iC:\compiler\include;C:\myinclude    

will have the same effect as:

-iC:\compiler\include -iC:\myinclude  


fin   refer to supplemental messages with the info label (default OFF).

By default, supplemental messages are labeled as supplemental. In PC-lint, such messages were labeled as info. If this flag is ON, the PC-lint behavior is used.


fit   thrown exception renders function not declared noexcept impure (default OFF).

If this flag is turned ON, then a throw expression within a function body will render that function impure unless the function is declared as not throwing any exceptions. This may be indicated by declaring the function noexcept. If a noexcept function contains a throw expression, the exception must be contained within the function.

When this flag is OFF, a throw expression will not render a function impure.

Note that throwing an exception is always considered to be a side effect associated with the local expression. This flag controls whether the enclosing function is further marked as impure which can affect whether a call to the function is considered to have side effects.


fiw   initialization is a write (default ON).

This flag is normally ON. When this flag is ON, any initialization is considered a Write to the variable being initialized (unless inhibited in some other way, see the fiz flag below). Two successive Writes to the same variable are flagged with Info 838. Thus:

int n = 3; 
n = 6; // Info 838

is normally greeted with message 838. If the flag is turned OFF (with a -fiw), the message would not be issued because the assignment of 6 to n would be considered the first Write. A subsequent Write without a Read would be unaffected by the flag and generate Info 838. See also Warning 438 , Info 838 and the -fiz flag below.


fiz   initialization by zero is a write (default ON).

This flag is normally ON. When this flag is ON, an initialization by 0 is considered a Write to the variable being initialized. Two successive Writes (without an intervening Read) to the same variable are flagged with Info 838. Thus in the code:

int n = 0; 
n = 6;       // Info 838 depends on fiz flag 
n = 16;      // Info 838 always

The assignment of 6 to n is normally greeted with message 838. If the flag is turned off (with a -fiz), the message would not be issued because the assignment to 6 would be considered the first Write. The subsequent assignment of 16 is flagged with Info 838.

See also messages 438 , 838 and the -fiw flag above.


fkp   use K&R preprocessor (default OFF).

ANSI/ISO C provides several facilities of the preprocessor that were not part of K&R C including the #elif directive and the defined keyword. If this flag is ON, use of these constructs will be warned about via messages 555 and 517 , respectively.


fla   locations for all diagnostics (default ON).

If this flag is ON, filename information will be provided even when the location does not correspond with a physical source file. In such cases, a representative filename that describes the location will be provided in angle brackets. For example, a location on the command line will be referenced as "<command line>", a location that represents a temporary buffer such as a macro expansion or string literal concatenation will be referenced as "<scratch space>", a location within the LINT environment variable will be referenced as "<LINT var>, etc. If this flag is OFF, the filename information will be empty in such cases.


flb   treat code as library (default OFF).

If ON, code is treated as belonging to a library header (See Section 5.1 Library Header Files ). Library code is not fully analyzed by default, see flag +flf for more information. That is, declared objects do not have to be used or defined and messages specified by -elib are suppressed. This flag has been largely superseded by the notion of "Library Header Files" (See Section 5.1 Library Header Files ). It still has its uses though. For example, the output of PC-lint Plus in preprocess mode (i.e. using the -p option) will contain Lint comments bearing ++flb before and –flb after the positions at which library headers were included.

This setting and unsetting of this flag is kept independently of the notion of library header (or module). Librariness of code is determined by an OR of this flag and the Librariness of the file. In this way, sections of a file can be library while the rest is not.


flf   process library functions (default OFF).

If this flag is OFF, non-dependent library function definitions will not be fully processed. This saves some time and avoids issues stemming from library headers making use of intrinsic functions unknown to PC-lint Plus. If this flag is ON, all library function definitions will be fully processed. When set to a value of 1 (+flf), library functions will not be walked during value tracking analysis. To enable value tracking within library functions, set this flag to a value of 2 (+flf ++flf). Setting this flag to a negative value (–flf) will disable processing of all library function bodies, including dependent functions.

See also the -skip_function option, which can be used to skip processing on a per-function basis.


fll   allow long long int (default OFF).

If the long-long flag is ON (option +fll) then long long int (or just long long) is a permitted type, which results in an integral quantity nominally different and usually longer than a long int. The size of a long long int can be specified with the option -sll# . If the long-long flag is not set, then you will be warned (Info 799 ) if an integral constant exceeds the size of a long.


flm   lock message format (default OFF).

This flag can be used by GUI front ends that depend on a particular format for error messages. If this flag is ON, the Message Presentation Options (See Section 4.3.3 Message Presentation ) are frozen. That is, subsequent -h , -width , and the various -format options are ignored. Also ignored is the -os option. The -os option (See Section 4.6.3 Output ) designates which file will receive error messages.


fln   honor #line directives for diagnostics (default ON).

By default, #line directives affect the location information within error messages. The option -fln may be used to ignore #line directives. See Section 18.3 #line and # .


flo   library declarations override non-library declarations (default OFF).

Since PC-lint Plus version 1.4, a symbol is considered to be a library symbol for the purpose of issuing global wrap-up messages only if all of the declarations of the symbol appeared in library regions. For example, if a non-library header is included in both a library region and a non-library region, its declarations are considered to be non-library as they did not exclusively appear in a library region. Previously, such symbols were considered library if any of the declarations for the symbol were encountered in a library region. As most global wrap-up messages are not issued for library symbols, the previous behavior could result in unintentional message suppressions. The previous behavior can be restored by turning this flag ON. Note that the +libh and +libdir options can be used to specify headers that should always be treated as library.

Note that when issuing a global wrap-up message for a non-library symbol, the message will be treated as if it originated from a non-library region (library suppressions will not be applied) even if the location at which PC-lint Plus actually issues the message is within a library region.


flp   lax null pointer constants (default OFF).

In C++98, a null pointer constant was defined as an integral constant expression that evaluates to zero. Post C++11 the definition was changed to "an integer literal with value zero or a prvalue of type std::nullptr_t". When in C++11 and later modes, an expression such as 1 - 1 or "\0" will therefore not be considered to be a null pointer constant by default. If this flag is ON then the more lax C++98 semantics will be applied for such expressions.


fls   assume external call chains modify static local variables (default OFF).

If this flag is ON, then it will be assumed that an external call that cannot be walked could modify static local variables (e.g. through a recursive call into the caller), invalidating their previous values. This flag is OFF by default, preserving the values of static local variables and precluding the possibility of external modification.


fma   microsoft inline asm blocks (default OFF).

This flag enables parsing support for Microsoft ASM blocks.


fme   enable metrics (default ON).

If this flag is OFF, then Metrics will be disabled.


fmi   enable supplemental mutex information messages (default OFF).

This flag controls the supplemental message information included with certain Thread Analysis messages. By default, supplemental information is provided for relevant references of any mutex, mutex attribute, or locker object included in the primary message. If this flag is ON, all references up to the location where the primary message is issued are provided in supplemental messages. If the value of this flag is 2 or greater (using ++fmi), supplemental messages are emitted for all mutex, mutex attribute, and locker objects up to the current location.


fml   metrics for library entities (default OFF).

If this flag is OFF, then checks and reports associated with Metrics will skip library entities. The value of the flo flag determines how the final library state is determined when an entity appears in multiple different contexts.


fms   microsoft semantics (default OFF).

Setting this flag enables a number of Microsoft specific extensions that are not of interest to other compilers and therefore do not have their own options. This flag also enables a number of undocumented features and emulates several MS-specific bugs including:

  • type definition in anonymous struct or union

  • pure specification on function definition defined at class scope

  • sealed, override, and __except contextual keywords

  • explicit specializations within class scope

  • forward references to enum types

  • flexible array member in unions and empty classes

  • support for throw(...) specification


fmt   match template template-arguments to compatible templates (default OFF).

C++17 allows a template template-parameter to bind to a template argument when the template parameter is at least as specialized as the template argument but the change as currently published is incomplete which can result in ambiguity errors for previously valid code. Because of this, the feature is not enabled by default but can be enabled by setting this flag to ON.


fmx   enable member access control in C++ (default ON).

This flag controls whether member access control is enabled in C++. If this flag is OFF, all members of classes will be accessible as if they had been declared public.


fnc   nested comments (default OFF).

If this flag is ON, comments may be nested. This allows PC-lint Plus to process files in which code has been ’commented out’. Commenting out code should not be considered good practice, however. Code should be disabled by using a preprocessor conditional as it avoids the quoted star-slash problem and it automatically assigns a condition to the re-enabling of the code.


fnf   fall back to operator new when new[] not available (default OFF).

If this flag is enabled and a placement new[] is called at a point where no valid array placement new declaration exists, instead of giving up, PC-lint Plus will try to "fall back" to a valid operator new function following Microsoft’s behavior. For example, given:

void *operator new(size_t n, void *p, size_t limit); 
 
int main() { 
   char buffer[100]; 
   char *p = new(buffer, sizeof(buffer)) char[10]; 
}

PC-lint Plus will emit

error 1024: no matching function for call to 'operator new[]' 
   char *p = new(buffer, sizeof(buffer)) char[10]; 
           ^ ~~~~~~~~~~~~~~~~~~~~~~~~

since there is no valid operator new[] available. With the fnf flag enabled, the operator new function will be used instead and no error will be issued.


fnn   new can return null (default OFF).

Turning this flag ON yields the old style operator new. That is, new may return NULL and does not throw an exception.

According to Standard C++, there are two built-in functions supporting operator new:

void *operator new( size_t ) throw( std::bad_alloc ); 
void *operator new[]( size_t ) throw( std::bad_alloc );

Rather than return NULL when there is no more allocatable space, these functions throw an exception as shown.

However, earlier versions of the language, especially before there were exceptions, returned NULL when storage was exhausted. To support this older convention, this flag was created.

When this flag is OFF, using std::nothrow will still be considered to possibly return null. Decrementing this flag (from the default value of 0) will force new to never return null, even when it is explicitly requested that new not throw an exception.


fnr   null pointer return (default OFF).

This flag is normally OFF. When this flag is ON, then all functions not available to be walked that return pointers and have no other return semantic are assumed to return pointers that could possibly be NULL. For example:

//lint +fnr    assume unavailable functions may return null 
int *f(); 
void g() { 
   int *p = f();      // p could be NULL 
   if (!p) { return; } // avoid a diagnostic 
   *p = 0;           // OK now to use p 
}

In this example, f was not available to be walked because no definition was present. A function may also be unavailable to be walked due to a -skip_function option, a no_specific_walk semantic, the current -vt_depth , or the value of the flf flag.


fnz   null pointers correspond to the integral value zero (default ON).

While it is not guaranteed by the C nor C++ standards, it is commonly assumed (and often but not necessarily true) that the integral representation of a null pointer in memory is zero. When this flag is ON, Value Tracking will treat the result of converting an integral value equal to zero to a pointer as yielding a null pointer even when the integral value is not a null pointer constant. If the flag is turned off then this assumption will not be made and only null pointer constants will be recognized. For example, when this flag is ON and -vt_depth=2 is used, this example:

1void invoke_callback(void(*cb)(unsigned int), unsigned int data) { 
2   cb(data); 
3} 
4 
5void callback_handler(unsigned int data) { 
6   char* p = (char*)data; 
7   *p = 42; 
8} 
9 
10int main() { 
11   invoke_callback(callback_handler, 0); 
12}

will report:

7  warning 413: likely use of null pointer 'p' 
   *p = 42; 
   ^~ 
2  supplemental 894: during specific walk callback_handler(0) 
   cb(data); 
   ^ 
... 
6  supplemental 831: cast from integer yields nullptr 
   char* p = (char*)data; 
           ^~~~~~~~~~~ 
... 
11  supplemental 831: argument passing yields 0 
   invoke_callback(callback_handler, 0); 
                               ^


fon   support for C++ operator name keywords (default ON).

When this flag is ON (the default), the C++ alternative operator names:

and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, and xor_eq

are recognized as keywords with meaning equivalent to the operators:

&&, &=, \&, |, ~, !, !=, ||, |=, ^, and ^=

respectively. If the value of this flag is 2 or higher, these operator names are also recognized in C mode (this is typically accomplished by #including iso646.h in C). If the flag is turned OFF, the alternative names are not recognized in C or C++.


fpa   pause before exiting (default OFF).

When this flag is ON, PC-lint Plus will pause just before exiting (after all messages are produced), and request input through stdin after prompting on stderr. Hitting Return (i.e., Enter) should be enough to finally terminate. This option could be useful in a setup where PC-lint Plus is launched in a separate terminal window that closes when PC-lint Plus exits, before the desired output can be reviewed. This option should keep the window open. CAUTION: This option is recommended only as a trouble shooting option or as a stop gap measure. Some environments require the launched program to terminate or they themselves lock up.


fpe   use precision of enumerators instead of explicit enum base type (default ON).

The precision of a value of enum type can be determined from the values representable by combinations of its enumerators or simply from the actual integer type used to represent the enum type. The former behavior occurs except as specified below.

If this flag is turned OFF, C++11 enumerations defined with a fixed underlying type will use the precision of the specified type instead.

If the value of this flag is negative (e.g. -fpe –fpe) then the actual integer type will always be used even for enum types without a fixed underlying type.

If the expression has volatile-qualified type then the actual integer type will always be used.

The actual integer underlying type is always used for enumerations that do not declare any enumerators.


fpm   limit precision to the maximum of the arguments (default OFF).

This is used to suppress certain kinds of Loss of Precision messages (734 ). In particular, if multiplication or left shifting is used in an expression involving char (or short where short is smaller than int) an unwanted loss of precision message may occur. For example, if ch is a char then:

ch = ch * ch  

would normally result in a Loss of Precision. This is suppressed when +fpm is set. This flag is automatically (and temporarily) set for operators <<= and *=. For example

ch <<= 1

is not greeted with Message 734.


fpn   pointer parameter may be null (default OFF).

If this flag is set ON, all pointer parameters are assumed to be possibly NULL and a diagnostic will be issued if a pointer parameter is used without testing for NULL. For example:

void f(char *p, char *q) { 
   *p = 3;    // warning only if +fpn 
   q++;       // warning only if +fpn 
} 
 
void g(char *p, char *q) { 
   if (p && q) { 
      *p = 3; // no warning 
      q++;   // no warning 
   } 
}

For more information about this interesting test see Chapter 8 Value Tracking .

When this flag is enabled and an instance of message 613 or 668 is reporting the use of an affected parameter, then it will additionally be parameterized with the text “pointer parameter assumed potentially NULL by +fpn” which enables finer control for -estring or -append . For example,

void f(int* p, int b) { 
   *p = 1; 
 
   int* q = 0; 
   if (b) { q = &b; } 
   *q = 1; 
}

will emit:

2 warning 613: potential use of null pointer ’p’ (pointer parameter assumed potentially NULL by +fpn)
6 warning 613: potential use of null pointer ’q’

when analyzed with +fpn.


fpo   limit precision to the type of the operation (default ON).

The precision of a mathematical operation is limited by the operation itself. For left shifting and right shifting, this flag is relevant only when the right hand operand is a known value. For left shifting, the resultant precision is first presumed to be the precision of the left hand operand plus the value of the right hand operand. For right shifting, the resultant precision is first presumed to be the precision of the left hand operand minus the value of the right hand operand. In both shifting cases, if the fpm flag is active, the precision is reduced to the smaller of that presumed precision and the precision of the left hand operand. If the fpo flag is active, the (possibly reduced) precision is reduced further still to the smaller of this reduced precision and the precision of the resultant type. For example:

void b(int c) { 
   char d; 
   d = c << 28; 
}

will result in info 734 , loss of precision, for the assignment regardless of whether or not this flag is active. When inactive, however, the precision reported in the message for the assigned value will be 59 bits and when active the precision will be 31 bits.

Likewise,

void b(int c) { 
   if ((c << 28) == 2147483648) 
      {} 
}

will produce 650 , constant ’2147483648’ out of range for operator ’==’, when fpo is active and will not if the flag is inactive for the same reasons.

This flag also limits the precision for multiplication. Initially, the precision of the result is presumed to be the maximum precision of the operands. A tentative precision that equals the sum of the precision of the two operands is also calculated. If the higher ranked operand is signed and a sign is not possible in either of the operands, the tentative precision is reduced by one. If either operand is a power of two, the (possibly reduced) tentative precision of the result is reduced by one. If the fpm flag is inactive, the initial precision of the result will be discarded and replaced with this (possibly reduced) tentative precision. If the fpo flag is active the precision of the result will then be reduced to the smaller of the precision of the result so far calculated and the precision of the resultant type. For example:

void b(int c) { 
   char d; 
   d = c * 28; 
}

will result in information 734 , loss of precision, for the assignment regardless of whether or not this flag is active. When inactive, however, the precision reported in the message for the assigned value will be 36 bits and when active the precision will be 31 bits.

Likewise,

void b(int c) { 
   if ((c << 28) == 34359738368) 
      {} 
}

will exhibit the same 650 behavior as described above in the case of left shifting for the same reasons.


fqb   qualifiers go before types (default ON).

This flag is normally ON and in conjunction with Elective Note 963 can report on declarations in which const and volatile qualifiers do not follow a consistent pattern as to whether they appear before or after types in a type specifier. By default Note 963 will report whenever a qualifier follows a type. If the fqb flag is turned OFF (e.g. -fqb) the qualifier is expected to follow the type. For example:

int const x;    // by default no message 
//lint +e963       turn on message 963 
int const y;    // msg 963: qualifier follows type 
const int z;    // no msg 
//lint -fqb       reverse the message 
int const a;    // no msg 
const int b;    // msg 963: qualifier precedes type

[?] and [?] provide supporting evidence that not only is a convention useful, but that the better convention is the one rendered with -fqb.


fql   execute queries in library regions (default ON).

When this flag is OFF (the default is ON), AST Queries created using the -astquery option are not evaluated for AST nodes appearing in library regions. The effect is similar to that which would be achieved by prefixing all AST Queries with !getLocation.isLibraryRegion except that 1) the flag may be set to OFF for a portion of the project to temporarily disable Query execution in library regions and 2) turning the flag OFF completely eliminates Query execution overhead in library regions which can be significant for projects that employ a large number of Queries.

The value of this flag is only considered during Query evaluation; its value at the time Queries are registered is irrelevant. When this flag is OFF, AST nodes residing in library regions are still accessible via AST traversal but AST Queries will not be evaluated for root nodes that reside in library regions. This flag does not have any effect on -equery options.


frc   remove commas before __VA_ARGS__ (default OFF).

The variadic macro feature added in C99 has a commonly encountered limitation: it requires that at least one argument be provided for the variadic portion of the argument list. For example:

#define LOG(format, ...) fprintf(stderr, format, __VA_ARGS__)

works fine when LOG is called with two or more arguments, e.g. LOG("%s", "Started"), but not when called with a single argument, e.g. LOG("Started"), which would expand to fprintf(stderr, "Started",) (note the trailing comma). As there is no facility provided by Standard C to address this limitation, various compilers have implemented their own extensions to deal with it.

GCC (and others) handle this by ascribing special meaning to the token pasting operator ## when placed between a comma and a variable argument in a macro definition, causing the offending comma to be removed during expansion if the variable argument is left out or empty. This allows the above to be defined as:

#define LOG(format, ...) fprintf(stderr, format, ##__VA_ARGS__)

and when invoked as LOG("Started") will expand to fprintf(stderr, "Started") (no trailing comma). PC-lint Plus supports this behavior regardless of the value of this flag but will issue message 2715 to alert of the non-portable behavior.

MSVC removes the trailing comma even without the appearance of the token pasting operator (as in the first example). This behavior is not enabled by PC-lint Plus by default, set this flag ON to enable support for this behavior.


frd   redefine default params for class template function members (default OFF).

When this flag is ON, default parameters for member functions of a class template may be redefined and the new value will be ignored. This behavior is implemented by MSVC.


frz   use return code only to indicate execution failure (default ON).

When this flag is ON, the exit code of PC-lint Plus will be 0 unless there was a fatal error. If this flag is OFF, the exit code will be the number of messages emitted, up to a max of 255 and can be manipulated with the -zero , -zero_err /+zero_err , and -exitcode options. If this flag is ON, the options that manipulate the exit code will have no effect.


fsc   strings are const char* even in C (default OFF).

When this flag is ON, string constants are considered pointers to const char. For example:

strcpy( "abc", buffer );      

draws a diagnostic because strcpy is declared within string.h (by all the major compiler venders) as

char * strcpy( char *, const char * );  

The diagnostic is issued because a const char * is being passed to a char *.

You may think it odd that string constants are not const char * by default. If you set this flag ON, you will probably discover the reason. There will undoubtedly be numerous places where a function is passed a string constant where the corresponding parameter should be declared const char * but isn’t. There will also be cases of variables that should be declared as const char * but aren’t. Thus, you may regard this flag as a good way to ferret out places where such type checking can be tightened.


fsd   output stack diagrams (default OFF).

When this flag is ON and stack reporting is enabled, debugging information presenting a visual aid of how stack memory was allocated within a function will be displayed. For example, for the following function:

void f(int x) { 
   double w; 
   { 
      int a; 
      int b; 
      int c; 
   } 
   float f; 
   { 
      double r; 
      double y; 
   } 
}

the +fsd option will produce:

### Auto Usage Stack Diagram for 'f' ### 
x [+4] -> 4, 4 
{ 
   w [+8] -> 12, 12 
   { 
      a [+4] -> 16, 16 
      b [+4] -> 20, 20 
      c [+4] -> 24, 24 
   } [-12] -> 12, 24 
   f [+4] -> 16, 24 
   { 
      r [+8] -> 24, 24 
      y [+8] -> 32, 32 
   } [-16] -> 16, 32 
} [-12] -> 4, 32 
###

where each new allocation (or complete block) is displayed in the format:

name [+added_size] -> current_usage, running_maximum_usage    


fse   use smallest underlying type for enums (default OFF).

In C, the underlying type of enumeration is implementation-defined but must be large enough to represent all the values in the enumeration as long as all of those values can be represented in an int. If all the values can be represented in a smaller signed or unsigned type, that smaller type may be used. In C++, the enumeration’s underlying type is the first of the following types that can represent all of the provided values: int, unsigned int, long, unsigned long, long long, unsigned long long. This flag indicates that the smallest type that can represent all of the values specified in the enumeration should be used as the underlying type.


fsf   display function names for semantics during calls (default OFF).

When this flag is ON, every encountered function call (including constructor calls) will be accompanied by info 879 , which provides all of the ways that the called function may be specified inside of -sem , -printf , and -scanf options. This is useful when attempting to provide semantics for specific function overloads or instantiations where the precise syntax may not be obvious.

If this flag is set to 2 (+fsf ++fsf) then 879 will instead be emitted for the first declaration of every function. This will include functions which are rarely called directly such as destructors.


fsi   search #include stack (default OFF).

When this flag is ON, in addition to searching the current working directory and the paths specified via -i options, header files specified with quoted syntax (e.g. #include "a.h", not #include <a.h>), are searched for in each of the directories of the current include stack, starting from the top.


fsl   single line comments (default OFF).

This flag controls whether C++-style comments are available in C89 mode.


fsn   treat strings as names (default ON).

When the flag is OFF, the esym() option can be used only to suppress messages parameterized by ’Symbol’. With this flag ON, esym() can also be employed to suppress (or enable) messages in the same way that -estring() can, e.g. messages parameterized by anything other than ’Type’ (for which -etype() must be used). For example:

//lint +fsn 
//lint -esym(650, <) 
int f(unsigned char c) 
{ 
   if (c < 1000) return 1;  // Potential 650 ("constant out of 
                        // range for operator 'String'") 
   else return 0; 
}

The -esym() second argument means that the 650 will not be issued when the operation (represented by the ’String’ parameter) is "<".


fso   return semantics override deduced return values (default OFF).

In previous versions, PC-lint would preserve the information in a user-defined return semantic even when more precise information was known about this value. The default behavior is to retain the more specific information. When the fso flag is ON, the PC-lint behavior is used. This applies only to functions with an implementation visible to PC-lint Plus.


fsp   specific calls (default ON).

If this flag is ON (it is by default), Specific function call walking is supported. See Section 8.8 Interfunction Value Tracking . By turning this flag OFF (using the option -fsp), processing can be speeded up.


fsv   track static variables (default ON).

Controls value tracking of static variables. When this flag is ON, all static variables will be tracked. If the flag is OFF, static variables will not be tracked between modules. Decrementing the flag when it is already OFF will disable tracking of static variables even within a single module.


fta   enable typographical ambiguity checks (default ON).

When this flag is ON, MISRA C 2012 typographical ambiguity calculations are performed. If you are not interested in these checks and do not want to incur the associated overhead of this feature, you can turn this flag off. See also message 9046 .


ftc   enable thread analysis checks (default ON).

If this flag is ON, thread analysis will be performed on the analyzed program (see Thread Analysis ). If the value of this flag is 2 or greater (using ++ftc), messages 2467 or 2468 will not inhibit the second phase of thread analysis (see Inhibition of Thread Analysis ). Thread analysis can be disabled by turning this flag OFF (-ftc).


ftg   permit trigraphs (default ON).

If this flag in ON (it is ON by default) standard C/C++ trigraphs are permitted and message 854 is issued when they are converted. For example ??( is a trigraph that denotes the left square bracket ([). If this flag is OFF, trigraphs will not be converted and trigraph sequences will instead result in the issuance of warning 584 .


fub   ignore unreachable break in switch (default ON).

When this flag is ON, message 527 will ignore a single redundant unreachable break statement in a case or default labeled region of a switch statement to accommodate the practice of ending all cases with a break statement even when a case unconditionally uses return, throw, continue, goto, or a function that does not return. Further unreachable code after the first such ignored break statement for a particular case will still be reported (including additional break statements).


fum   user declared move deletes only corresponding copy (default OFF).

In Standard C++, a user-declared move operation causes both the copy constructor and copy assignment function to be deleted. When this flag is set, only the corresponding operation will be deleted, e.g a user-declared move constructor will not result in the copy assignment function being deleted. This option is provided to support MSVC behavior.


fun   issue additional stack usage notes (default OFF).

If this flag is ON, note 2901 (which must be separately enabled) will be issued with information about each function. This outputs the same information as note 974 , but is not restricted to the worst-case function.


fup   treat null pointer values as unknown after reporting them (default OFF).

When this flag is ON (+fup) a pointer will only be reported as null a single time until there is further reason to believe it may be null. If a potentially null pointer is dereferenced multiple times in a row, only the first will be reported. When this flag is set to 2 (+fup ++fup) a pointer will be completely cleared after it has been reported as null, including discarding information about what the pointer would point to if it were not null. When this flag is set to -1 (-fup –fup) a pointer that has been reported as null will then be assumed not to be null on the basis that it has already been dereferenced.

For example:

1void f(bool b) { 
2   int* a = nullptr; 
3   if (b) { a = new int; } 
4   *a = 0; 
5   int z = *a; 
6   z = 5 / *a; 
7   if (a) { } 
8}

Analyzing this file (with the arguments +fia -w1 +e613 +e414 +e593 +e774 -h1 for presentation) will emit:

4  warning 613: potential use of null pointer 'a' 
5  warning 613: potential use of null pointer 'a' 
6  warning 613: potential use of null pointer 'a' 
6  warning 414: possible division by zero 
8  warning 593: custodial pointer 'a' possibly not freed nor returned

If -fup –fup is added, then after the first instance of 613 is emitted it will be assumed that a cannot be null because it was dereferenced. This will avoid subsequent instances of 613 and cause message 774 to be emitted when it is tested later:

4  warning 613: potential use of null pointer 'a' 
6  warning 414: possible division by zero 
7  info 774: boolean condition for 'if' always evaluates to 'true' 
   (involving variable 'a') 
8  warning 593: custodial pointer 'a' possibly not freed nor returned

If +fup is added instead, the only difference will be that message 613 is only emitted once:

4  warning 613: potential use of null pointer 'a' 
6  warning 414: possible division by zero 
8  warning 593: custodial pointer 'a' possibly not freed nor returned

Finally, if +fup ++fup is used, the first 613 will completely clear the value of a and prevent any further messages in the example:

4  warning 613: potential use of null pointer 'a'


fur   allow unions to contain reference members (default OFF).

C++ forbids unions to contain reference members and by default PC-lint Plus does not allow this either. If this flag is ON, reference members will be accepted inside of unions.


fuu   treat uninitialized values as unknown after reporting them (default OFF).

When this flag is ON values will be completely cleared once they have been reported as uninitialized (and thus will not be reported as uninitialized again on a second use).


fuv   report unreferenced variables that could be const (default OFF).

When this flag is OFF, unreferenced variables that could be made const (or pointer to const, etc.) will not be reported. When this flag is ON, unreferenced variables are eligible to be reported as could be const.


fvd   interactive value tracking debugger (default OFF).

This flag enables the value tracking debugger. See section 8.7 Debugger


fwu   wchar_t is unsigned (default OFF).

This flag is used to specify the signedness of a built-in wchar_t type. If this flag is set ON the built-in type is of the unsigned variety, otherwise of the signed variety.


fxt   extern C functions can throw exceptions (default OFF).

If this flag is ON, extern "C" functions are assumed to be capable of throwing exceptions unless specified otherwise such as by the GCC nothrow attribute. By default, it is assumed that extern "C" functions don’t throw exceptions.


fzd   enable sized deallocations (default OFF).

This option controls whether the C++14 sized deallocation feature is enabled.


fzl   sizeof is long (default OFF).

If this flag is ON, sizeof() is assumed to be a long (or unsigned long if -fzu is also ON). The flag is OFF by default because sizeof is normally typed int. This flag is automatically adjusted upon encountering a size_t type. This flag is useful on architectures where int is not the same size as long.

If the flag has a value equal to 2, then sizeof() is assumed to be long long. Thus

+fzl ++fzl    

will result in sizeof() being unsigned long long x (assuming +fzu).


fzu   sizeof is unsigned (default ON).

If this flag is ON, sizeof() is assumed to return an unsigned quantity (unsigned long if fzl is also ON). This flag is automatically adjusted upon encountering a size_t type.


4.12 Compiler Adaptation

All compilers are slightly different owing largely to differences in libraries and preprocessor variables, if not to differences in the language processed. If automated configuration support is available for your compiler then the easiest way to cope with these differences is the use of the pclp_config.py utility provided in the distribution. See section 2.3.2 to get started with pclp_config.py. The remainder of this section describes how many compiler extensions can be supported using PC-lint Plus options.

4.12.1 Customization Facilities

The following are useful for supporting a number of features in a variety of compilers. With some exceptions, they are used mostly to get PC-lint Plus to ignore some nonstandard constructs accepted by some compilers.

@ Compilers for embedded systems frequently use the @ notation to specify the location of a variable.

We have for this reason support for the @ feature, which consists of ignoring expressions to its right. When we see a ’@’ we then give a warning (430 ), which you may suppress with a -e430. For example:

int *p @ location + 1;  

Although warning 430 is issued, p is regarded as a validly initialized pointer to int.

_gobble is a reserved word that needs to be activated via +rw(_gobble).

It causes the next token to be gobbled; i.e., it and the next token are ignored. This is intended to be used with the -d option. See co-kcarm.lnt for examples.

_ignore_init This keyword when activated causes the initializer of a data declaration or the body of a function to be ignored.

Cross compilers for embedded systems frequently have declarations that associate addresses with variables. For example, they may have the following declarations

Port pa = 0xFFFF0001; 
Port pb = 0xFFFF0002;

etc. The type Port is, of course, non-standard. The programmer may decide to define Port, for the purpose of linting, to be an unsigned char by using the following option:

-d"Port=unsigned char"  

(The quotes are necessary to get a blank to be accepted as part of the definition.) However, PC-lint Plus gives a warning when it sees a small data item being initialized with such large values. The solution is to use the built-in reserved word _ignore_init. It must be activated using the +rw option. Then it is normally used by embedding it within a -d option. For the above example, the appropriate options would be:

+rw(_ignore_init) 
 -d"Port=_ignore_init unsigned char"

The keyword _ignore_init is treated syntactically as a storage class (though for maximum flexibility it does not have to be the ONLY storage class). Its effect is to cause PC-lint Plus to ignore, as its name suggests, any initializer of any declaration in which it is embedded.

Some compilers allow wrapping a C/C++ function prototype around assembly language in a fashion similar to the following:

__asm int a(int n, int m) 
{ xeo 3, (n)r ; ... }

Note there is a special keyword that introduces such a function. This keyword may vary across compilers. To get PC-lint Plus to ignore the function body, equate this keyword with _ignore_init. E.g.

+rw(_ignore_init) 
-d__asm = _ignore_init

_to_brackets is a reserved word that will cause it and the immediately following bracketed, parenthesized or braced expression, if any, to be ignored.

It needs to be activated with +rw(_to_brackets). It is usually accompanied with a -d option. (For example, see co-iar.lnt on the distribution media). For example, the option:

-dinterrupt=_to_brackets 
+rw(_to_brackets)

will cause each of the following to be ignored.

interrupt(3) 
interrupt[5,5] 
interrupt{x,x}

_to_eol When _to_eol is encountered in a program (or more likely some identifier defined to be _to_eol), the identifier and all remaining information on the line is skipped.

That is, information is ignored to the End Of Line. E.g., suppose the following nonstandard construct is valid for some compiler:

int f( int n ) registers readonly ( 3, 4 ) 
{ 
return n; 
}

Then the user may use the following options so that the rest of the line following the first ’)’ is ignored:

-dregisters=_to_eol 
+rw(_to_eol)

_to_semi is a super gobbler that will cause PC-lint Plus to ignore this and every token up to and including a semi-colon.

It needs to be enabled with +rw(_to_semi) and needs to be equated using -d . For example, if keyword _pragma begins a semicolon-terminated clause that you want PC-lint Plus to ignore, you would need two options:

-d_pragma=_to_semi 
+rw(_to_semi)

_up_to_brackets

is a potential reserved word that will cause it and all tokens up to and including the next bracketed (or braced parenthesized) expression to be ignored. For example:

//lint +rw(_up_to_brackets)   activate reserved word 
//lint -dasm=_up_to_brackets  asm is now an _up_to_brackets 
asm ( "abc" : "def" );    // "asm" ... ')' is ignored 
asm volatile ( "asm" );   // "asm" ... ')' is ignored

In the above we almost could have defined asm to be a _to_brackets. The problem is that we also needed to ignore the volatile following asm and so we required the use of _up_to_brackets.

__typeof__ is similar in spirit to sizeof except it returns the type of its expression rather than its size.

Since it is not part of standard C or C++ the reserved word must be activated with the option:

+rw( __typeof__ )      

__typeof__ can be useful in macros where the exact type of an argument is not known.

For example:

#define SWAP(a,b) { __typeof__(a) x = a; a = b; b = x; }       

will serve to swap the values of a and b. Some compilers not only support the __typeof__ facility but they write their headers in terms of it. For example,

typedef __typeof__(sizeof(0)) size_t;  

assures that size_t will not be out of synch with the built-in type.

One such condition is output produced by the scavenger whose purpose is to extract pre-defined macro definitions from an unwitting compiler.

-dname{definition} is an alternative to -dname=definition.

-dname{definition} has the advantage that blanks may be embedded in the definition. Now it is true that you could use -d"name=definition" and so enclose blanks in that fashion but there are certain conditions, especially compiler generated macro definitions where the use of quotation marks are not suitable.

-dname()=Replacement
-dname(identifier-list)=Replacement

To induce PC-lint Plus to ignore or reinterpret a function-like sequence it is only necessary to #define a suitable function-like macro. However, this would require modifying source code (or use of the -header option) and is hence not as convenient as using this option. For example, if your compiler supports

char_varyingn  

as a type and you want to get PC-lint Plus to interpret this as char* you can use

-dchar_varying()=char*  

As another example:

//lint -dalpha(x,y)=((x+y)/x) 
int n=alpha(2,10);

will initialize n to 6. The above -dalpha... option is equivalent to:

#define alpha(x,y) ((x+y)/x)  

In the no parameter case, the functional expression can have any number of arguments. For example; in the following code both asm() expressions are ignored even though they have a different number of arguments.

//lint -dasm()= 
 
void f() 
{ asm("Move a,2", "Add a,b"); 
 asm("Jmp.x"); 
}

As with the normal (non-functional) version of the -d option the +d variant of the option sets up a macro that cannot be redefined.

4.12.2 Identifier Characters

Additional identifier characters can be established. See -$ and -ident() in Section 4.4.3 Tokenizing .

4.12.3 Preprocessor Statements

See Section 18.4 Non-Standard Preprocessing for special non-standard preprocessor statements. Also see the +ppw option.

4.12.4 In-line assembly code

Compiler writers have shown no dearth of creativity in their invention of new syntax to support assembly language.

In the PC world, the most frequently used convention is (to simplify slightly):

asm { assembly-code }  

or

asm assembly-code <new-line>  

where asm is sometimes replaced with either _asm or __asm. This convention is supported automatically by enabling the asm keyword, using +rw(asm) (or +rw(_asm) or +rw(__asm) as the case may be).

But other conventions exist as well. One manufacturer uses

#asm 
   assembly-code 
#

For this sequence, it is necessary to enable asm as a pre-processor word using +ppw(asm)

If your compiler uses a different preprocessor word, you may use the option +ppw_asgn .

Another sequence is:

#asm 
   assembly-code 
#endasm

For this +ppw(asm,endasm) is needed.

Yet another convention is:

#pragma asm 
   assembly-code 
#pragma endasm

For this you need to define the two pragmas with

+pragma(asm, off) 
+pragma(endasm, on)

4.12.5 Pragmas

4.12.6 Built-in pragmas

A number of compilers support the push_macro and the pop_macro pragmas.

push_macro( name-in-quotes ), where the name-in-quotes specifies a macro, is a pragma that will save the definition of the macro onto a stack. This will allow the macro to be redefined or undefined over a sub-portion of a module. Presumably this will be followed by a pop_macro( name-in-quotes ) pragma that will restore the original macro. Thus:

#define N 100 
#pragma push_macro( "N" ) 
#define N 1000 
int x[N]; 
#pragma pop_macro( "N" ) 
int y[N];

declares x to be an array of 1000 integers whereas y becomes an array of 100 integers.

Note that you have, in effect, k different stacks where k is the number of different names provided as arguments to these pragmas.

4.12.7 User pragmas

+pragma( identifier,Action ) associates Action with identifier for #pragma
-pragma( identifier ) disables pragma identifier

The +pragma( identifier, Action ) option can be used to specify an identifier that will be used to trigger an Action when the identifier appears as the first identifier of a #pragma statement. Action must be one of

on 
off 
once 
message 
ppw 
macro 
fmacro 
options 
include_alias

Please note that the purpose of the +pragma option is compatibility with your compiler. If your goal is to conditionally compile depending on the presence of PC-lint Plus, use the _lint preprocessor variable.

on and off – An off action will turn processing off. An on option will reset processing. For example, assume that the following coding sequence appears in a user program:

#pragma ASM 
   movereg 3,8(4) 
#pragma ENDASM

Lint will normally ignore the #pragma statements but it will not ignore the assembly language between the #pragma statements, which might lead to a flurry of messages. To resolve the problem, add the pair of options:

+pragma( ASM, off ) 
+pragma( ENDASM, on )

This will turn off lint processing when the ASM is seen and turn it back on when the ENDASM is seen.

Please do not get this backwards. See Section 4.12.4 In-line assembly code .

once: The option +pragma(identifier,once) allows the programmer to establish an arbitrary identifier (usually the identifier once) as an indicator that the header is to be included just once. To mimic the Microsoft C++ compiler use the option: +pragma(once,once). Then, a subsequent appearance of the pragma:

#pragma once  

within a header will cause that header to be included just once. Subsequent attempts to include the header within the same module will be ignored.

message: The option +pragma(identifier, message) allows the programmer to establish an arbitrary identifier (usually the identifier message) as a pragma that will produce a message to standard out. For example:

+pragma(message,message)      

will cause the pragma:

#pragma message "hello from file" __FILE__    

to write to standard out a greeting identifying the file within which the pragma is contained. As this example shows, macros are expanded as encountered in the message line. Also, messages fall under control of the conditional compilation statements, #if, etc. Following the Microsoft compiler, if the first token is a left parenthesis then only the parenthetical expression will be output. Other information on the line is not output.

ppw: The option +pragma( indentifier, ppw ) will endow identifier with the ppw pragma action, which means reprocess the line as a preprocessor statement but with the word "pragma" ignored. Thus:

//lint +pragma( include, ppw ) 
#pragma include "abc.h"

will give the pragma keyword "include" the pragma action ppw, which will cause the next line to operate just like a standard #include preprocessor line.

macro, fmacro and options: Pragmas provide an avenue for the programmer to communicate to a compiler that is not governed by the syntax of the language. In most cases PC-lint Plus can ignore this information. Occasionally, however, the programmer will want us to act on this information so that he, the programmer, is not inserting the information twice, once for his compiler and once for PC-lint Plus.

Obviously it is impossible to provide compatible pragma recognition for all compilers now and into the future. The best general method of handling this seems to be to convert the pragma into a macro. Through the macro definition process, the macro can then become whatever the programmer wants. In particular it can become a /*lint options...*/ comment and thereby be converted into a PC-lint Plus option. Alternatively it can be converted into code.

There are three basic ways of converting a pragma into a macro; these are identified as pragma types macro, fmacro and options.

macro: If a pragma is identified as macro as in the option

+pragma( identifier, macro )    

then when a pragma by that name is encountered, the name is prefixed with the string ’pragma_’ and all the information to the right of the identifier is enclosed in parentheses. For example, one compiler supports statements such as:

#pragma port x @ 0x100  

This would identify x as a particular I/O port. Later in the program there may be assignments to or from x. If PC-lint Plus were to ignore the pragma, it would have to emit syntax errors on every use of x.

If the option +pragma( port,macro ) is given, the above pragma will be converted into:

pragma_port( x @ 0x100 )      

Presumably there is a macro definition that resembles:

#define pragma_port( s ) volatile unsigned s;  

Such a definition can be placed in a header file that only PC-lint Plus will see by utilizing the -header option.

fmacro: The second form of macroizing a pragma is identified as fmacro (meaning function macro). This would be used in a +pragma option having the form:

+pragma( identifier, fmacro )    

With the fmacro type, instances of the pragma are assumed to already be in functional notation. Like the macro type, the name of the pragma is prefixed with pragma_ to avoid conflicts with other uses of the pragma name. Aside from this prefixing the pragma is taken as found in the pragma statement and employed as a macro. For example, consider a pragma called warnings, which appears as:

#pragma warnings(no)  

or

#pragma warnings(yes)  

Presumably the no form turns off warnings and the yes form turns them back on.

If the option +pragma(warnings,fmacro) is given, the first pragma will be converted into:

pragma_warnings(no)    

and the second will be converted into:

pragma_warnings(yes)  

The programmer will want to provide a set of macros that can convert these pragmas into the equivalent form for PC-lint Plus. This could be done as follows:

#define pragma_warnings(x) pragma_warnings_##x 
#define pragma_warnings_no /*lint -save -w1 */ 
#define pragma_warnings_yes /*lint -restore */  

These macro definitions can be placed in a header file that only PC-lint Plus will see by utilizing the -header option.

options: The third form of pragma that can be macroized is identified as ’options’ using an option of the form:

+pragma( identifier, options )  

When a pragma having the name identifier is used, it is presumably followed by a blank-separated sequence of options having the form name=value. An example is:

#pragma OPTIONS tab=4 length=80

In this form, each individual option becomes a potential macro invocation. The name of this macro is formed by concatenating pragma_, the identifier, which in this case is OPTIONS, followed by underscore and the name of the suboption. Thus for the suboption tab the name of the macro is pragma_OPTIONS_tab. As an example, suppose the option +pragma( OPTIONS, options ) is given and the following macro defined.

#define pragma_OPTIONS_tab(x) /*lint -t##x */  

Then the above pragma will result in just the single macro invocation:

pragma_OPTIONS_tab(x)  

This will invoke the tab option of PC-lint Plus. The ’length=80’ option is ignored. To attach meaning to the length option it would only be necessary to define a macro whose name would be pragma_OPTIONS_length.

include_alias: The option +pragma(identifier, include_alias) allows the programer to indicate an arbitrary identifier as mimicking the Microsoft C/C++ compiler pragma include_alias. For example:

+pragma(alias_include, include_alias)  

will cause the pragmas:

#pragma alias_include( "a.h", "123.h" )

to inform Lint, when a #include directive appears for "a.h", to search for "123.h" instead.

identifier: This option -pragma( identifier ) will remove the pragma whose name is identifier. Thus:

-pragma(message)

will remove the message pragma.

4.12.8 Arbitrary Width Integer Types

Integer types with an arbitrary number of bits (between 2 and 65,536 bits for signed types and 1 and 65,536 bits for unsigned types) are supported as exact-width types using the type specifier _BitInt(n) where n is the number of bits used to represent the type. _BitInt types are signed by default and may be combined with the signed or unsigned keywords. For example, the following will define uint40_t as a typedef for an unsigned 40-bit type:

typedef unsigned _BitInt(40) uint40_t;

The -d option can be used to define compiler-specific keywords as macros that expand to the equivalent _BitInt type, e.g. -d_bit"=unsigned _BitInt(1)".

Although this type specifier is part of the C23 language standard, its use will be allowed in analysis of any C or C++ language mode.