### 3.5 Additional warning options ¶

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.

`-W` ¶

  This is a general option similar to `-Wall` which warns about a selection of common programming errors, such as functions which can return without a value (also known as “falling off the end of the function body”), and comparisons between signed and unsigned values. For example, the following function tests whether an unsigned integer is negative (which is impossible, of course):

      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.

`-Wconversion` ¶

  This option warns about implicit type conversions that could cause unexpected results, such as conversions between floating-point and integer types, between signed and unsigned types and between types of different width (e.g. long and short integers). Conversions can occur in expressions and assignments, and in calls to functions if the types of the arguments do not match those specified in the prototype.

  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.

`-Wshadow` ¶

  This option warns about the redeclaration of a variable name in a scope where it has already been declared. This is referred to as variable shadowing, and causes confusion about which occurrence of the variable corresponds to which value.

  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.

`-Wcast-qual` ¶

  This option warns about pointers that are cast to remove a type qualifier, such as `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.

`-Wwrite-strings` ¶

  This option implicitly gives all string constants defined in the program a `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.

`-Wtraditional` ¶

  This option warns about parts of the code which would be interpreted differently by an ANSI/ISO compiler and a “traditional” pre-ANSI compiler.12 When maintaining legacy software it may be necessary to investigate whether the traditional or ANSI/ISO interpretation was intended in the original code for warnings generated by this option.

The options above produce diagnostic warning messages, but allow the compilation to continue and produce an object file or executable. For large programs it can be desirable to catch all the warnings by stopping the compilation whenever a warning is generated. The `-Werror` option changes the default behavior by converting warnings into errors, stopping the compilation whenever a warning occurs.

#### Footnotes

##### (12)

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.