Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<!-- Crown Copyright (c) 1998 -->
<HTML>
<HEAD>
<TITLE>C Checker Reference Manual: Preprocessing checks</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
<A NAME=S70>
<H1>C Checker Reference Manual</H1>
<H3>January 1998</H3>
<A HREF="tdfc10.html"><IMG SRC="../images/next.gif" ALT="next section"></A>
<A HREF="tdfc8.html"><IMG SRC="../images/prev.gif" ALT="previous section"></A>
<A HREF="tdfc1.html"><IMG SRC="../images/top.gif" ALT="current document"></A>
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
</A>
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
<HR>
<DL>
<DT><A HREF="#S71"><B>6.1 </B> - Introduction</A><DD>
<DT><A HREF="#S72"><B>6.2 </B> - Preprocessor directives
</A><DD>
<DT><A HREF="#S73"><B>6.3 </B> - Indented Preprocessing Directives</A><DD>
<DT><A HREF="#S74"><B>6.4 </B> - Multiple macro definitions</A>
<DD>
<DT><A HREF="#S75"><B>6.5 </B> - Macro arguments</A><DD>
<DT><A HREF="#S76"><B>6.6 </B> - Unmatched quotes</A><DD>
<DT><A HREF="#S77"><B>6.7 </B> - Include depth</A><DD>
<DT><A HREF="#S78"><B>6.8 </B> - Text after #endif</A><DD>
<DT><A HREF="#S79"><B>6.9 </B> - Text after #</A><DD>
<DT><A HREF="#S80"><B>6.10 </B> - New line at end of file</A><DD>
</DL>
<HR>
<H1>6 Preprocessing checks</H1>
<A NAME=S71>
<HR><H2>6.1 Introduction</H2>
This chapter describes tchk's capabilities for checking the preprocessing
constructs that arise in C.<P>
<A NAME=S72>
<HR><H2>6.2 <A NAME=1>Preprocessor directives </H2>
By default, the TenDRA C checker understands those preprocessor directives
specified by the ISO C standard, section 6.8, i.e. #if, #ifdef, #ifndef,
#elif, #else, #endif, #error, #line and #pragma. As has been mentioned,
#pragma statements play a significant role in the checker. While any
recognised #pragma statements are processed, all unknown pragma statements
are ignored by default. The check to detect unknown pragma statements
is controlled by:<P>
<PRE>
#pragma TenDRA unknown pragma <EM>permit</EM>
</PRE>
The option for <EM>permit</EM> are <CODE>disallow</CODE> (raise an
error if an unknown pragma is encountered), <CODE>warning</CODE> (allow
unknown pragmas with a warning), or <CODE>allow</CODE> (allow unknown
pragmas without comment).<P>
In addition, the common non-ISO preprocessor directives, #file, #ident,
#assert, #unassert and #weak may be permitted using:<P>
<PRE>
#pragma TenDRA directive <EM>dir</EM> allow
</PRE>
where <EM>dir</EM> is the appropriate one of <CODE>file</CODE>, <CODE>ident
</CODE>, <CODE>assert</CODE>, <CODE>unassert</CODE> or <CODE>weak</CODE>.
If <CODE>allow</CODE> is replaced by <CODE>warning</CODE> then the
directive is allowed, but a warning is issued. In either case, the
modifier <CODE>(ignore) </CODE>may be added to indicate that, although
the directive is allowed, its effect is ignored. Thus for example:<P>
<PRE>
#pragma TenDRA directive ident (ignore) allow
</PRE>
causes the checker to ignore any #ident directives without raising
any errors.<P>
Finally, the directive dir can be disallowed using:<P>
<PRE>
#pragma TenDRA directive <EM>dir</EM> disallow
</PRE>
Any other unknown preprocessing directives cause the checker to raise
an error in the default mode. The pragma may be used to force the
checker to ignore such directives without raising any errors.<P>
<PRE>
#pragma TenDRA unknown directive allow
</PRE>
<CODE>Disallow</CODE> and <CODE>warning</CODE> variants are also available.<P>
<A NAME=S73>
<HR><H2>6.3 <A NAME=7>Indented Preprocessing Directives</H2>
The ISO C standard allows white space to occur before the # in a preprocessing
directive, and between the # and the directive name. Many older preprocessors
have problems with such directives. The checker's treatment of such
directives can be set using:<P>
<PRE>
#pragma TenDRA indented # directive <EM>permit</EM>
</PRE>
which detects white space before the # and:<P>
<PRE>
#pragma TenDRA indented directive after # <EM>permit</EM>
</PRE>
which detects white space between the # and the directive name. The
options for <EM>permit</EM> are <CODE>allow</CODE>, <CODE>warning</CODE>
or <CODE>disallow</CODE> as usual. The default checking profile allows
both forms of indented directives.<P>
<A NAME=S74>
<HR><H2>6.4 <A NAME=9>Multiple macro definitions</H2>
The ISO C standard states that, for two definitions of a function-like
macro to be equal, both the spelling of the parameters and the macro
definition must be equal. Thus, for example, in:<P>
<PRE>
#define f( x ) ( x )
#define f( y ) ( y )
</PRE>
the two definitions of f are not equal, despite the fact that they
are clearly equivalent. Tchk has an alternative definition of macro
equality which allows for consistent substitution of parameter names.
The type of macro equality used is controlled by:<P>
<PRE>
#pragma TenDRA weak macro equality allow
</PRE>
where permit is <CODE>allow</CODE> (use alternative definition of
macro equality),<CODE>warning</CODE> (as for allow but raise a warning),
or <CODE>disallow</CODE> (use the ISO C definition of macro equality
- this is the default setting).<P>
More generally, the pragma: <P>
<PRE>
#pragma TenDRA extra macro definition allow
</PRE>
allows macros to be redefined, both consistently and inconsistently.
If the definitions are incompatible, the first definition is overwritten.
This pragma has a <CODE>disallow</CODE> variant, which resets the
check to its default mode. <P>
<A NAME=S75>
<HR><H2>6.5 <A NAME=11>Macro arguments</H2>
According to the ISO C standard, section 6.8.3, if a macro argument
contains a sequence of preprocessing tokens that would otherwise act
as a preprocessing directive, the behaviour is undefined. Tchk allows
preprocessing directives in macro arguments by default. The check
to detect such macro arguments is controlled by:<P>
<PRE>
#pragma TenDRA directive as macro argument <EM>permit</EM>
</PRE>
where <EM>permit</EM> is <CODE>allow</CODE>, <CODE>warning</CODE>
or <CODE>disallow</CODE>.<P>
The ISO C standard, section 6.8.3.2, also states that each # preprocessing
token in the replacement list for a function-like macro shall be followed
by a parameter as the next preprocessing token in the replacement
list. By default, if tchk encounters a # in a function-like macro
replacement list which is not followed by a parameter of the macro
an error is raised. The checker's behaviour in this situation is controlled
by: <P>
<PRE>
#pragma TenDRA no ident after # <EM>permit</EM>
</PRE>
where the options for <EM>permit</EM> are <CODE>allow</CODE> (do not
raise errors), <CODE>disallow</CODE> (default mode) and <CODE>warning</CODE>
(raise warnings instead of errors). <P>
<A NAME=S76>
<HR><H2>6.6 <A NAME=15>Unmatched quotes</H2>
The ISO C standard, section 6.1, states that if a ` or " character
matches the category of preprocessing tokens described as "single
non-whitespace-characters that do not lexically match the other preprocessing
token categories", then the behaviour is undefined. For example:<P>
<PRE>
#define a `b
</PRE>
would result in undefined behaviour. By default the ` character is
ignored by tchk. A check to detect such statements may be controlled
by:<P>
<PRE>
#pragma TenDRA unmatched quote <EM>permit</EM>
</PRE>
<EM>The usual</EM><CODE> allow</CODE>, <CODE>warning</CODE> and <CODE>disallow
</CODE> options are available.<P>
<A NAME=S77>
<HR><H2>6.7 <A NAME=17>Include depth</H2>
Most preprocessors set a maximum depth for #include directives (which
may be limited by the maximum number of files which can be open on
the host system). By default, the checker supports a depth equal to
this maximum number. However, a smaller maximum depth can be set using:<P>
<PRE>
#pragma TenDRA includes depth n
</PRE>
where <CODE>n</CODE> can be any positive integral constant.<P>
<A NAME=S78>
<HR><H2>6.8 <A NAME=19>Text after #endif</H2>
The ISO C standard, section 6.8, specifies that #endif and #else preprocessor
directives do not take any arguments, but should be followed by a
newline. In the default checking mode, tchk raises an error when #endif
or #else statements are not directly followed by a new line. This
behaviour may be modified using:<P>
<PRE>
#pragma TenDRA text after directive <EM>permit</EM>
</PRE>
where <EM>permit</EM> is <CODE>allow</CODE> (no errors are raised
and any text on the same line as the #endif or #else statement is
ignored), <CODE>warning</CODE> or <CODE>disallow</CODE>.<P>
<A NAME=S79>
<HR><H2>6.9 <A NAME=21>Text after #</H2>
The ISO C standard specifies that a # occuring outside of a macro
replacement list must be followed by a new line or by a preprocessing
directive and this is enforced by the checker in default mode . The
check is controlled by:<P>
<PRE>
#pragma TenDRA no directive/nline after ident <EM>permit</EM>
</PRE>
where <EM>permit</EM> may be <CODE>allow, disallow</CODE> or
<CODE>warning</CODE>.<P>
<A NAME=S80>
<HR><H2>6.10 <A NAME=23>New line at end of file</H2>
The ISO C standard, section 5.1.1.2, states that source files must
end with new lines. Files which do not end in new lines are flagged
as errors by the checker in default mode. The behaviour can be modified
using:<P>
<PRE>
#pragma TenDRA no nline after file end <EM>permit</EM>
</PRE>
where <EM>permit</EM> has the usual <CODE>allow</CODE><EM>,</EM><CODE>
disallow</CODE> and <CODE>warning</CODE> options.<P>
<!-- FM pgf ignored -->
<HR>
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
Copyright © 1998.</I></P>
</BODY>
</HTML>