GCC provides many other warning options that are not included in -Wall but are often useful. Typically these produce warnings for source code which may be technically valid but is very likely to cause problems. The criteria for these options are based on experience of common errors—they are not included in -Wall because they only indicate possibly problematic or “suspicious” code.
Since these warnings can be issued for valid code it is not necessary to compile with them all the time. It is more appropriate to use them periodically and review the results, checking for anything unexpected, or to enable them for some programs or files.
int foo (unsigned int x) { if (x < 0) return 0; /* cannot occur */ else return 1; }
Compiling this function with -Wall does not produce a warning,
$ gcc -Wall -c w.c
but does give a warning with -W:
$ gcc -W -c w.c w.c: In function `foo': w.c:4: warning: comparison of unsigned expression < 0 is always false
In practice, the options -W and -Wall are normally used
together.
For example, the integer absolute value function int abs(int i)
is easily confused with the corresponding floating-point function
double fabs(double x)
. This can lead to incorrect results, as
shown in the following program:
#include <stdio.h> #include <stdlib.h> int main (void) { double x = -3.14; double y = abs(x); /* should be fabs(x) */ printf ("x = %g |x| = %g\n", x, y); return 0; }
Compiling this function with -Wall does not produce a warning,
$ gcc -Wall wabs.c
$ ./a.out
x = -3.14 |x| = 3 (incorrect)
but does give a warning with -Wconversion:
gcc -Wall -Wconversion wabs.c wabs.c: In function `main': wabs.c:8: warning: passing arg 1 of `abs' as integer rather than floating due to prototype
The -Wconversion option also catches errors such as the assignment of a negative value to an unsigned variable, as in the following code,
unsigned int x = -1;
This is technically allowed by the ANSI/ISO C standard (with the
negative integer being converted to a positive integer, according to the
machine representation) but could be a simple programming error. If you
need to perform such a conversion you can use an explicit cast, such as
(unsigned int)-1
, to avoid any warnings from this option. On
two's-complement machines the cast of -1 gives the maximum number
that can be represented by an unsigned integer.
The following function declares a local variable y
that shadows
the declaration in the body of the function:
double test (double x) { double y = 1.0; { double y; y = x; } return y; }
This is valid ANSI/ISO C, where the return value is 1. The shadowing of
the variable y
might make it seem (incorrectly) that the return
value is x
, when looking at the line y = x
(especially in
a large and complicated function).
Shadowing can also occur for function names. For example, the following
program attempts to define a variable sin
which shadows the
standard function sin(x)
.
double sin_series (double x) { /* series expansion for small x */ double sin = x * (1.0 - x * x / 6.0); return sin; }
This error will be detected by the -Wshadow option.
const
. For example, the following function
discards the const
qualifier from its input argument, allowing it
to be overwritten:
void f (const char * str) { char * s = (char *)str; s[0] = '\0'; }
The modification of the original contents of str
is a
violation of its const
property. This option will warn about the
improper cast of the variable str
which allows the string to
be modified.
const
qualifier, causing a compile-time warning if there is an
attempt to overwrite them. The result of modifying a string constant is
not defined by the ANSI/ISO standard, and the use of writable string
constants is deprecated in GCC.
[1] The traditional form of the C language was described in the original C reference manual “The C Programming Language (First Edition)” by Kernighan and Ritchie.