Some nonportable code is flagged by lint
in its default behavior, and a few more cases are diagnosed when lint
is invoked with -p and/or -Xc.
The latter tells lint to check
for constructs that do not conform to the ANSI C standard.
For the messages issued under -p and -Xc,
In some C language implementations,
character variables that are not explicitly
declared signed or unsigned
are treated as signed quantities with a
range typically from -128 to 127.
In other implementations, they are treated as
with a range typically from 0 to 255.
So the test
where EOF has the value -1,
will always fail on machines where character
variables take on nonnegative values.
One of lint's -p checks
will flag any comparison that implies
a ``plain'' char may have a negative
Note, however, that declaring c a signed char
in the above example eliminates the diagnostic,
not the problem.
That's because getchar() must return all
possible characters and a distinct EOF value,
so a char cannot store its value.
This example, which is perhaps the most
common one arising from implementation-defined
sign-extension, shows how a thoughtful
application of lint's portability
option can help you discover bugs not related to portability.
In any case, declare c as an int.
c = getchar();
if (c == EOF) . . .
A similar issue arises with bit-fields.
When constant values are
assigned to bit-fields, the field may be too
small to hold the value.
On a machine that treats bit-fields of type int
as unsigned quantities, the values allowed for
int x:3 range from 0 to 7, whereas on machines
that treat them as signed quantities
they range from -4 to 3.
However unintuitive it may seem, a three-bit field
declared type int cannot hold the value 4
on the latter machines.
lint invoked with -p
flags all bit-field types other
than unsigned int or signed int.
Note that these are the only portable
The compilation system supports int, char,
short, and long bit-field types
that may be unsigned, signed, or ``plain.''
It also supports the enum bit-field type.
Bugs can arise when a larger-sized
type is assigned to a smaller-sized type.
If significant bits are truncated, accuracy is lost:
s = l;
lint flags all such assignments by default;
the diagnostic can be suppressed by invoking the -a option.
Bear in mind that you may be suppressing
other diagnostics when you invoke lint with this or
any other option.
Check the list in
for the options that suppress more than one diagnostic.
A cast of a pointer to one object type to a
pointer to an object type with stricter alignment
requirements may not be portable.
because, on most machines, an int cannot start on an
arbitrary byte boundary, whereas a char can.
If you suppress the diagnostic by invoking lint
with -h, you may be disabling other messages.
You can eliminate the problem
by using the generic pointer void .
ANSI C leaves the order of evaluation of complicated
What this means is that when function calls, nested assignment
statements, or the increment and decrement operators
cause side effects -- when
a variable is changed as a byproduct of the
evaluation of an expression -- the order
in which the side effects take place is highly machine dependent.
By default, lint flags any variable
changed by a side effect and used elsewhere
in the same expression:
int i = 1;
a[i++] = i;
Note that in this example the value of a may
be 1 if one compiler is used, 2 if another.
The bitwise logical operator & can also give
rise to this diagnostic when it is mistakenly
used in place of the logical operator &&:
if ((c = getchar()) != EOF & c != '0')
© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003