Subversion Repositories tendra.SVN

Rev

Blame | Last modification | View Log | RSS feed

<!-- Crown Copyright (c) 1998 -->
<HTML>
<HEAD>
<TITLE>C Checker Reference Manual: Dialect Features</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
<A NAME=S81>
<H1>C Checker Reference Manual</H1>
<H3>January 1998</H3>
<A HREF="tdfc11.html"><IMG SRC="../images/next.gif" ALT="next section"></A>
<A HREF="tdfc9.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="#S82"><B>7.1 </B> - Introduction</A><DD>
<DT><A HREF="#S83"><B>7.2 </B> - Resolving linkage problems</A><DD>
<DT><A HREF="#S84"><B>7.3 </B> - Identifier linkage</A><DD>
<DT><A HREF="#S85"><B>7.4 </B> - Implicit integer types</A><DD>
<DT><A HREF="#S86"><B>7.5 </B> - Bitfield types</A><DD>
<DT><A HREF="#S87"><B>7.6 </B> - Extra type definitions</A><DD>
<DT><A HREF="#S88"><B>7.7 </B> - Static block level functions</A><DD>
<DT><A HREF="#S89"><B>7.8 </B> - Incomplete array element types</A><DD>
<DT><A HREF="#S90"><B>7.9 </B> - Forward enumeration declarations</A><DD>
<DT><A HREF="#S91"><B>7.10 </B> - Untagged compound types</A><DD>
<DT><A HREF="#S92"><B>7.11 </B> - External volatility</A><DD>
<DT><A HREF="#S93"><B>7.12 </B> - Identifier name length</A><DD>
<DT><A HREF="#S94"><B>7.13 </B> - Ellipsis in function calls</A><DD>
<DT><A HREF="#S95"><B>7.14 </B> - Conditional lvalues</A><DD>
<DT><A HREF="#S96"><B>7.15 </B> - Unifying the tag name space</A><DD>
<DT><A HREF="#S97"><B>7.16 </B> - Initialisation of compound types</A><DD>
<DT><A HREF="#S98"><B>7.17 </B> - Variable initialisation</A><DD>
<DT><A HREF="#S99"><B>7.18 </B> - Escape sequences</A><DD>
<DT><A HREF="#S100"><B>7.19 </B> - $ in identifier names</A><DD>
<DT><A HREF="#S101"><B>7.20 </B> - Writeable string literals</A><DD>
<DT><A HREF="#S102"><B>7.21 </B> - Concatenation of character string
literals and wide character string literals</A><DD>
<DT><A HREF="#S103"><B>7.22 </B> - Nested comments</A><DD>
<DT><A HREF="#S104"><B>7.23 </B> - Empty source files</A><DD>
<DT><A HREF="#S105"><B>7.24 </B> - Extra commas</A><DD>
<DT><A HREF="#S106"><B>7.25 </B> - Extra semicolons</A><DD>
<DT><A HREF="#S107"><B>7.26 </B> - Compatibility with C++ to TDF producer</A>
<DD>
</DL>

<HR>
<H1>7  Dialect Features</H1>
<A NAME=S82>
<HR><H2>7.1  Introduction</H2>
This chapter describes the capabilities of the TenDRA C checker for
enforcing the ISO C standard as well as features for detecting areas
left undefined by the standard. It also lists the non-ISO dialect
features supported by the checker in order to provide compatibility
with older versions of C and allow the use of third-party source which
may contain non-standard constructs.<P>
<A NAME=S83>
<HR><H2>7.2  <A NAME=1>Resolving linkage problems</H2>
Often the way that identifier names are resolved can alter the semantics
of a program. For example, in:<P>
<PRE>
        void f () {
                {
                        extern void g ();
                        g ( 3 );
                }
                g ( 7 );
        }
</PRE>
the external declaration of g is only in scope in the inner block
of f. Thus, at the second call of g, it is not in scope, and so is
inferred to have declaration:<P>
<PRE>
        extern int g ();
</PRE>
(see 3.4). This conflicts with the previous declaration of g which,
although not in scope, has been registered in the external namespace.
The pragma:<P>
<PRE>
        #pragma TenDRA unify external linkage on
</PRE>
modifies the algorithm for resolving external linkage by searching
the external namespace before inferring a declaration. In the example
above, this results in the second use of g being resolved to the previous
external declaration. The <CODE>on</CODE> can be replaced by <CODE>warning
</CODE> to give a warning when such resolutions are detected, or <CODE>off
</CODE> to switch this feature off.<P>
Another linkage problem, which is left undefined in the ISO C standard,
is illustrated by the following program:<P>
<PRE>
        int f () {
                extern int g ();
                return ( g () );
        }
        
        static int g ()
        {
                return ( 0 );
        }
</PRE>
Is the external variable g (the declaration of which would be inferred
if it was omitted) the same as the static variable g? Of course, had
the order of the two functions been reversed, there would be no doubt
that they were, however, in the given case it is undefined. By default,
the linkage is resolved externally, so that the two uses of g are
not identified. However, the checker can be made to resolve its linkage
internally, so that the two uses of g are identified. The resolution
algorithm can be set using:<P>
<PRE>
        #pragma TenDRA linkage resolution : <EM>action</EM>
</PRE>
where <CODE>action</CODE> can be one of:<P>
<OL>
<LI><CODE>(internal) on</CODE><P>
<LI><CODE>(internal) warning</CODE><P>
<LI><CODE>(external) on</CODE><P>
<LI><CODE>(external) warning</CODE><P>
<LI><CODE>off</CODE><P>
</OL>
depending on whether the linkage resolution is internal, external,
or default, and whether a warning message is required. The most useful
behaviour is to issue a warning for all such occurrences (by setting
action to (internal) warning, for example) so that the programmer
can be alerted to clarify what was intended.<P>
<A NAME=S84>
<HR><H2>7.3  <A NAME=5>Identifier linkage</H2>
The ISO C standard, section 6.1.2.2, states that &quot;if, within
a translation unit, an identifier appears with both internal and external
linkage, the behaviour is undefined&quot;. By default, the checker
silently declares the variable with external linkage. The check to
detect variables which are redeclared with incompatible linkage is
controlled using:<P>
<PRE>
        #pragma TenDRA incompatible linkage <EM>permit</EM>
</PRE>
where <EM>permit</EM><CODE> </CODE><EM>may be </EM><CODE>allow</CODE>
(default mode), <CODE>warning</CODE> (warn about incompatible linkage)
or <CODE>disallow</CODE> (raise errors for redeclarations with incompatible
linkage).<P>
<A NAME=S85>
<HR><H2>7.4  <A NAME=7>Implicit integer types</H2>
Older C dialects allow external variables to be specified without
a type, the type int being inferred. Thus, for example:<P>
<PRE>
        a, b;
</PRE>
is equivalent to:<P>
<PRE>
        int a, b;
</PRE>
By default these inferred declarations are not permitted, though tchk's
behaviour can be modified using:<P>
<PRE>
        #pragma TenDRA implicit int type for external declaration <EM>permit</EM>
</PRE>
where <EM>permit</EM> is <CODE>allow</CODE>, <CODE>warning</CODE>
or <CODE>disallow</CODE>.<P>
A more common feature, allowed by the ISO C standard, but considered
bad style by some, is the inference of an int return type for functions
defined in the form:<P>
<PRE>
        f ( int n ) {
                ....
        }
</PRE>
the checker's treatment of such functions can be determined using:<P>
<PRE>
        #pragma TenDRA implicit int type for function return <EM>permit
</EM>
</PRE>
where <CODE>permit</CODE> can be <CODE>allow</CODE>, <CODE>warning</CODE>
or <CODE>disallow</CODE>.<P>
<A NAME=S86>
<HR><H2>7.5  <A NAME=9>Bitfield types</H2>
The ISO C standard only allows signed int, unsigned int and their
equivalent types as type specifiers in bitfields. Using the default
checking profile, tchk raises errors for other integral types used
as type specifiers in bitfields.This behaviour may be modified using
the pragma:<P>
<PRE>
        #pragma TenDRA extra int bitfield type <EM>permit</EM>
</PRE>
<CODE>Permit</CODE> is one of <CODE>allow</CODE> (no errors raised),
<CODE>warning</CODE> (allow non-int bitfields through with a warning)
or <CODE>disallow</CODE> (raise errors for non-int bitfields). <P>
If non-int bitfields are allowed, the bitfield is treated as if it
had been declared with an int type of the same signedness as the given
type. The use of the type char as a bitfield type still generally
causes an error, since whether a plain char is treated as signed or
unsigned is implementation-dependent. The pragma:<P>
<PRE>
        #pragma TenDRA character<EM> set-sign</EM>
</PRE>
where <CODE>set-sign</CODE> is <CODE>signed</CODE>, <CODE>unsigned</CODE>
or <CODE>either</CODE>, can be used to specify the signedness of a
plain char bitfield. If <EM>set-sign</EM> is <CODE>signed</CODE> or
<CODE>unsigned</CODE>, the bitfield is treated as though it were declared
signed char or unsigned char respectively. If <EM>set-sign</EM> is
<CODE>either</CODE>, the sign of the bitfield is target-dependent
and the use of a plain char bitfield causes an error.<P>
<A NAME=S87>
<HR><H2>7.6  <A NAME=13>Extra type definitions</H2>
In accordence with the ISO C standard, in default mode tchk does not
allow a type to be defined more than once using a typedef. The pragma:<P>
<PRE>
        #pragma TenDRA extra type definition <EM>permit</EM>
</PRE>
where <CODE>permit</CODE> is <CODE>allow</CODE> (silently accepts
redefinitions, provided they are consistent), <CODE>warning</CODE>
or <CODE>disallow</CODE>.<P>
<A NAME=S88>
<HR><H2>7.7  <A NAME=15>Static block level functions</H2>
The ISO C standard (Section 6.5.1) states that the declaration of
an identifier for a function that has block scope shall have no explicit
storage-class specifier other than extern. By default, tchk raises
an error for declarations which do not conform to this rule. The behaviour
can be modified using:<P>
<PRE>
        #pragma TenDRA block function static <EM>permit</EM>
</PRE>
where <CODE>permit</CODE> is <CODE>allow</CODE> (accept block scope
function declarations with other storage-class specifiers), <CODE>disallow
</CODE> or <CODE>warning</CODE>. <P>
<A NAME=S89>
<HR><H2>7.8  <A NAME=17>Incomplete array element types</H2>
The ISO C standard (Section 6.1.2.5) states that an incomplete type
e.g an undefined structure or union type, is not an object type and
that array elements must be of object type. The default behaviour
of the checker causes errors when incomplete types are used to specify
array element types. The pragma: <P>
<PRE>
        #pragma TenDRA incomplete type as object type <EM>permit</EM>
</PRE>
can be used to alter the treatment of array declarations with incomplete
element types. <EM>Permit</EM> is one of <CODE>allow</CODE>, <CODE>disallow
</CODE> or <CODE>warning</CODE> as usual.<P>
<A NAME=S90>
<HR><H2>7.9  <A NAME=19>Forward enumeration declarations</H2>
The ISO C Standard (Section 6.5.2.3) states that the first introduction
of an enumeration tag shall declare the constants associated with
that tag. This rule is enforced by the checker in default mode, however
it can be relaxed using the pragma: <P>
<PRE>
        #pragma TenDRA forward enum declaration <EM>permit</EM>
</PRE>
where replacing <CODE>permit</CODE> by <CODE>allow</CODE> permits
the declaration and use of an enumeration tag before the declaration
of its associated enumeration constants. A <CODE>disallow</CODE> variant
which restores the default behaviour is also available.<P>
<A NAME=S91>
<HR><H2>7.10  <A NAME=21>Untagged compound types</H2>
The ISO C standard states that a declaration must declare at least
a declarator, a tag or the members of an enumeration. The checker
detects such declarations and, by default, raises an error. The severity
of the errors can be altered by: <P>
<PRE>
        #pragma TenDRA unknown struct/union <EM>permit</EM>
</PRE>
where <CODE>permit</CODE> may be <CODE>allow</CODE> to allows code
such as: <P>
<PRE>
        struct {int i; int j;};
</PRE>
through without errors (statements such as this occur in some system
headers) or <CODE>disallow</CODE> to restore the default behaviour.<P>
<A NAME=S92>
<HR><H2>7.11  <A NAME=23>External volatility</H2>
The inclusion of the pragma: <P>
<PRE>
                #pragma TenDRA external volatile_t
</PRE>
instructs the checker thereafter to treat any object declared with
external linkage (ISO C standard Section 6.1.2.2) as if it were volatile
(ISO C standard Section 6.5.3). This was a feature of some traditional
C dialects. In the default mode, objects with external linkage are
only treated as volatile if they were declared with the volatile type
qualifier.<P>
<A NAME=S93>
<HR><H2>7.12  <A NAME=25>Identifier name length</H2>
Under the ISO C standard rules on identifier name length, an implementation
is only required to treat the first 31 characters of an internal name
and the first 6 characters of an external name as significant. The
TenDRA C checker provides a facility for users to specify the maximum
number of characters allowed in an identifier name, to prevent unexpected
results when the application is moved to a new implementation. The
limit is set using:<P>
<PRE>
        #pragma TenDRA set name limit <EM>integer_constant</EM>
</PRE>
There is currently no distinction made between external and internal
names for length checking. Identifier name lengths are not checked
in the default mode.<P>
<A NAME=S94>
<HR><H2>7.13  <A NAME=27>Ellipsis in function calls</H2>
An ellipsis is not an identifier and should not be used in a function
call, even if, as in the program below, the function prototype contains
an ellipsis: <P>
<PRE>
        int f(int a,...) {
                return 1; }
        int main() {
                int x, y;
                x=f(y ,...);
                return 1;
        }
</PRE>
In default mode the checker raises an error if an ellipsis is used
as a parameter in a function call. The severity of this error can
be modified by using: <P>
<PRE>
        #pragma TenDRA ident ... <EM>permit</EM>
</PRE>
If <CODE>permit</CODE> is replaced by <CODE>allow</CODE> the ellipsis
is ignored, if <CODE>warning</CODE> is used tchk produces a warning
and if <CODE>disallow</CODE> is used the default behaviour is restored.<P>
<A NAME=S95>
<HR><H2>7.14  <A NAME=29>Conditional lvalues</H2>
The ? operator cannot normally be used to define an lvalue, so that
for example, the program:<P>
<PRE>
        struct s {int a, b; };
        void f (int n,struct s *s1,struct s *s2) {
                ( n ? s1: s2)-&gt;a = 0;
        }
</PRE>
is not allowed in ISO C. The pragma:<P>
<PRE>
        #pragma TenDRA conditional lvalue allow
</PRE>
allows conditional lvalues if:<P>
<OL>
<LI>Both options of the conditional operator have compatible compound
types;<P>
<LI>Both options of the conditional are lvalues.<P>
</OL>
(there is also a <CODE>disallow</CODE> variant, but <CODE>warning</CODE>
is not permitted in this case).<P>
<A NAME=S96>
<HR><H2>7.15  <A NAME=31>Unifying the tag name space</H2>
Each object in the tag name space is associated with a classification
(struct, union or enum) of the type to which it refers. If such a
tag is used, it must be preceded by the correct classification, otherwise
the checker produces an error by default. However, the pragma:<P>
<PRE>
        #pragma TenDRA ignore struct/union/enum tag <EM>status</EM>
</PRE>
may be used to change the severity of the error. The options for <EM>status
</EM>are: <CODE>on </CODE>(allows a tag to be used with any of the
three classifications, the correct classification being inferred from
the type definition), <CODE>warning</CODE> or <CODE>off</CODE>.<P>
<A NAME=S97>
<HR><H2>7.16  <A NAME=33>Initialisation of compound types</H2>
Many older C dialects do not allow the initialisation of automatic
variables of compound type. Thus, for example:<P>
<PRE>
        void f () {
                struct {
                        int a;
                        int b;
                } x = { 3, 2 };
        }
</PRE>
would not be allowed by some older compilers, although by default
tchk does not raise any errors since the code is legal according to
the ISO C standard. The checker's behaviour may be changed using:<P>
<PRE>
        #pragma TenDRA initialization of struct/union (auto) <EM>permit</EM>
</PRE>
where <CODE>permit</CODE> is <CODE>allow</CODE>, <CODE>warning</CODE>
or <CODE>disallow</CODE>. This feature is particularly useful when
developing a program which is intended to be compiled with a compiler
which does not support automatic compound initialisations.<P>
<A NAME=S98>
<HR><H2>7.17  <A NAME=35>Variable initialisation</H2>
The ISO C standard (Section 6.5.7) states that all expressions in
an initialiser for an object that has static storage duration or in
an initialiser-list for an object that has aggregate or union type
shall be constant expressions. The pragma: <P>
<PRE>
        #pragma TenDRA variable initialization <EM>permit</EM>
</PRE>
may be used to allow non-constant initialisers if <EM>permit</EM>
is replaced by <CODE>allow</CODE>. The other option for <EM>permit</EM>
is <CODE>disallow</CODE> which restores the default behaviour of flagging
non-constant initialisers for objects of static storage duration as
errors.<P>
<A NAME=S99>
<HR><H2>7.18  <A NAME=36>Escape sequences</H2>
The ISO C standard specifies a small set of escape sequences in strings,
for example \n as newline. Unknown escape sequences lead to an error
in the default mode , however the severity of the error may be altered
using:<P>
<PRE>
        #pragma TenDRA unknown escape <EM>permit</EM>
</PRE>
where <EM>permit</EM> is <CODE>allow</CODE> (silently replaces the
unknown escape sequence, \z say, by z), <CODE>warning</CODE> or <CODE>disallow
</CODE>.<P>
<A NAME=S100>
<HR><H2>7.19  <A NAME=39>$ in identifier names</H2>
The ISO C standard (Section 6.1) states that the use of the character
$ in identifier names is illegal. The pragma: <P>
<PRE>
        #pragma TenDRA dollar as ident allow
</PRE>
can be used to allow such identifiers, which by default are flagged
as errors. There is also a <CODE>disallow</CODE> variant which restores
the default behaviour. <P>
<A NAME=S101>
<HR><H2>7.20  <A NAME=41>Writeable string literals</H2>
The ISO C standard, section 6.1.4, states that &quot;if the program
attempts to modify a string literal of either form, the behaviour
is undefined&quot;. Assignments to string literals of the form:<P>
<PRE>
        &quot;abc&quot;='3';
</PRE>
always result in errors. Other attempts to modify members of string
literals, e.g.<P>
<PRE>
        &quot;abc&quot;[1]='3';
</PRE>
are permitted in the default checking mode. This behaviour can be
changed using:<P>
<PRE>
        #pragma TenDRA writeable string literal <EM>permit</EM>
</PRE>
where <EM>permit</EM> may be <CODE>allow</CODE>, <CODE>warning</CODE>
or <CODE>disallow</CODE>.<P>
<A NAME=S102>
<HR><H2>7.21  <A NAME=43>Concatenation of character string literals
and wide character string literals</H2>
The ISO C standard, section 6.1.4, states that if a character string
literal is adjacent to a wide character string literal, the behaviour
is undefined. By default, this is flagged as an error by the checker.
If the pragma:<P>
<PRE>
        #pragma TenDRA unify incompatible string literal <EM>permit</EM>
</PRE>
is used, with <EM>permit</EM> set to <CODE>allow</CODE> or <CODE>warning</CODE>
the character string literal is converted to a wide character string
literal and the strings are concatenated, although in the <CODE>warning</CODE>
case a warning is output. <EM>The</EM><CODE> disallow</CODE> version
of the pragma restores the default behaviour.<P>
<A NAME=S103>
<HR><H2>7.22  <A NAME=45>Nested comments</H2>
The occurence of the `/*' characters inside a C comment, i.e. text
surrounded by the `/*' and `*/' symbols, is usually a mistake and
can lead to the termination of a comment unexpectedly. By default
such nested comments are processed silently, however an error or warning
can be produced by setting:<P>
<PRE>
        #pragma TenDRA nested comment analysis <EM>status</EM>
</PRE>
with <EM>status</EM> as <CODE>on</CODE> or <CODE>warning</CODE>. If
<EM>status</EM> is <CODE>off</CODE> the default behaviour is restored.<P>
<A NAME=S104>
<HR><H2>7.23   
<A NAME=50>Empty source files</H2>
The ISO standard states that each source file should contain at least
one declaration or definition. Source files which contain no external
declarations or definitions are flagged as errors by the checker in
default mode. The severity of the error may be altered using:<P>
<PRE>
        #pragma TenDRA no external declaration <EM>permit</EM>
</PRE>
where the options for <CODE>permit</CODE> are <CODE>allow</CODE> (no
errors raised), <CODE>warning</CODE> or <CODE>disallow</CODE>.<P>
<A NAME=S105>
<HR><H2>7.24  <A NAME=52>Extra commas</H2>
The ISO C standard does not allow extra commas in enumeration type
declarations e.g. <P>
<PRE>
        enum e = {red, orange, yellow,};
</PRE>
The extra comma at the end of the declaration is flagged as an error
by default, but this behaviour may be changed by using: <P>
<PRE>
        #pragma TenDRA extra , <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>
<A NAME=S106>
<HR><H2>7.25  <A NAME=54>Extra semicolons</H2>
Some dialects of C allow extra semicolons at the external declaration
and definition level in contravention of the ISO C standard. For example,
the program:<P>
<PRE>
        int f () {
                return ( 0 );
        };
</PRE>
is not ISO compliant. The checker enforces the ISO rules by default,
but the errors raised may be reduced to warning or suppressed entirely
using:<P>
<PRE>
        #pragma TenDRA extra ; <EM>permit</EM>
</PRE>
with <EM>permit</EM> as <CODE>warning</CODE> or <CODE>allow</CODE>.
The <CODE>disallow</CODE> option restores the default behaviour.<P>
<A NAME=S107>
<HR><H2>7.26  <A NAME=56>Compatibility with C++ to TDF producer</H2>
In the interests of compatibility between the C checker and the new
C++ checker, all pragmas beginning:<P>
<PRE>
        #pragma TenDRA ++
</PRE>
are silently ignored by tchk.<P>
<P>
<!-- FM pgf ignored -->
<HR>
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
Copyright &copy; 1998.</I></P>
</BODY>
</HTML>