@node manywarnings
@section manywarnings

The @code{manywarnings} module enables many GCC warnings for your
package.  Here is an example use:

@smallexample
AC_ARG_ENABLE([gcc-warnings],
  [AS_HELP_STRING([[--enable-gcc-warnings[=TYPE]]],
    [control generation of GCC warnings.  The TYPE 'no' disables
     warnings; 'yes' (default) generates cheap warnings;
     'expensive' in addition generates expensive warnings.])])

AS_IF([test "$enable_gcc_warnings" != no],
  [
   # Set up the list of unwanted warning options.
   nw=
   if test "$enable_gcc_warnings" != expensive; then
     nw="$nw -fanalyzer"
   fi
   nw="$nw -Wbad-function-cast" # Casting a function's result is not more
                                # dangerous than casting any other value.
   nw="$nw -Winline"            # It's OK to not inline.
   nw="$nw -Wsign-compare"      # Too many false alarms.
   nw="$nw -Wstrict-overflow"   # It's OK to optimize strictly.
   nw="$nw -Wsystem-headers"    # Don't warn in system headers.

   # Setup the list of meaningful warning options for the C compiler.
   # The list comes from manywarnings.m4. Warning options that are not
   # generally meaningful have already been filtered out (cf.
   # build-aux/gcc-warning.spec).
   gl_MANYWARN_ALL_GCC([possible_warning_options])

   # Compute the list of warning options that are desired.
   gl_MANYWARN_COMPLEMENT([desired_warning_options],
                          [$possible_warning_options], [$nw])
   # Compute the list of remaining undesired warning options.
   # Namely those, that were not in manywarnings.m4 because they were
   # already listed in build-aux/gcc-warning.spec; this includes those
   # that are implied by -Wall.
   gl_MANYWARN_COMPLEMENT([remaining_undesired_warning_options],
                          [$nw], [$possible_warning_options])

   # Add the desired warning options to WARN_CFLAGS.
   for w in $desired_warning_options; do
     gl_WARN_ADD([$w])
   done

   # Add the opposites of the remaining undesired warning options to
   # WARN_CFLAGS.
   for w in `echo "$remaining_undesired_warning_options" | sed -e 's/-W/-Wno-/g'`; do
     gl_WARN_ADD([$w])
   done
])
@end smallexample

This module sets up many GCC warning options.

When you use it for the first time, it is common practice to do it as
follows:

@itemize @bullet
@item
Start with the newest major release of GCC.
This will save you time, because some warning options produce many false
alarms with older versions of GCC (such as @code{-Wstrict-overflow} or
@code{-Wunsafe-loop-optimizations}).
@item
Consider the platforms commonly used when enabling GCC warnings.
This includes not only target architectures and operating systems, but also
optimization options, which can greatly affect the warnings generated.
Makefiles generated by @code{configure} default to @option{-O2} optimization.
If you also commonly build with @option{-O0} or other optimization options,
you can compile again with those options.
Using more optimizations catches more bugs, because the compiler does
a better static analysis of the program when optimizing more.
Also, some warning options that diagnose suboptimal code generation,
such as @code{-Winline}, are not effective when not optimizing.
On the other hand, if it's frequent to build the package with warnings but
without optimizations, for debugging purposes, then you don't want to see
undesired warnings in these phases of development either.
@item
Compile the package with an empty @code{nw} value, that is, with all
possible warnings enabled.
@item
Then you will go through the list of warnings.
Since there are likely many warnings, the first time, it's a good idea
to sort them by warning option first:
@smallexample
$ grep warning: make-output.log \
  | sed -e 's/^\(.*\) \[\(-W.*\)\]$/\2  \1/' | sort -k1
@end smallexample
@item
You will likely deactivate warnings that occur often and don't point to
mistakes in the code, by adding them to the @samp{nw} variable, then
reconfiguring and recompiling.
When warnings point to real mistakes and bugs in the code, you will of
course not disable them but fix your code to silence the warning
instead.

Many GCC warning options usually don't point to mistakes in the code;
these warnings enforce a certain programming style.
It is a project management decision whether you want your code to follow
any of these styles.
Note that some of these programming styles are conflicting.
You cannot have them all; you have to choose among them.

When a warning option pinpoints real bugs occasionally, but it also
whines about a few code locations which are fine, we recommend to leave
the warning option enabled.
Whether you then live with the remaining few warnings, or choose to
disable them one-by-one through
@code{#pragma GCC diagnostic ignored "@var{option}"}
(@pxref{Diagnostic Pragmas,,, gcc, Using the GNU Compiler Collection},
@url{https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html}),
is again a project management decision.
@end itemize

When a new major version of GCC is released, the Gnulib maintainers add
the newly available warning options into the @code{gl_MANYWARN_ALL_GCC}
macro.
You will then enjoy the benefits of the new warnings, simply by updating
to the newest Gnulib.
If some of the new warnings are undesired, you can add them to the
@samp{nw} variable, as described above.

Comments on particular warning flags:

@table @samp

@item -fanalyzer
The @code{manywarnings} module by default uses GCC's
@option{-fanalyzer} option, as this issues some useful warnings.
(It can also help GCC generate better code.)
However, @code{-fanalyzer} can greatly slow down compilation,
and in programs with large modules it can be so slow as to be unusable,
so it is common for @command{configure} to disable it unless
@command{configure} is given an option like
@option{--enable-gcc-warnings=expensive}.

@item -fstrict-aliasing
Although the @code{manywarnings} module does not enable GCC's
@option{-fstrict-aliasing} option, it is enabled by default if you
compile with @code{-O2} or higher optimization, and can help GCC
generate better warnings.

@item -Wanalyzer-malloc-leak
The @code{-fanalyzer} option generates many false alarms about
@code{malloc} leaks, which @code{manywarnings} suppresses by also
using @option{-Wno-analyzer-malloc-leak}.

@item -fstrict-flex-arrays
The @code{manywarnings} module by default uses GCC's
@option{-fstrict-flex-arrays} option if available, so that GCC can
warn about nonportable usage of flexible array members.
In a few cases this can help GCC generate better code,
so it is not strictly a warning option.

@item -Wsign-compare
GCC and Clang generate too many false alarms with @option{-Wsign-compare},
and we don't recommend that warning.  You can disable it by using
@code{gl_WARN_ADD([-Wno-sign-compare])} as illustrated above.
Programs using Gnulib generally don't enable
that warning when compiling Gnulib code.  If you happen to find a real
bug with that warning we'd like to know it.

@end table
