Dealing with GCC warnings in external headers

Good style for C projects is interpreting all warnings as errors, this method helps to avoid lots of mistakes and hidden bugs. With GCC it can be achieved with -Wall -Werror flags (first one turns on all the warnings, second one makes GCC interpret them as errors, refer to docs for more details).

But what if you really need to use some external header which was not written in a good style?

Sometimes you need to use some heavy library with dozens or even hundreds of dirty pieces of code which GCC don't like. It will be painful to fix every single line (and may be then find out that some warnings actually make this library useless for you). Instead, you may try to use a trick.

Take a look at the following example:

bad_header.h: /* Let's skip header guards to be short */
#include

static inline void some_func(void) {
  printf("This function prints %d ints!\n");
}

Using such header will lead to compilation error even if your source files are fine:

#include <stdio.h>

#include "bad_header.h"

int main(int argc, char **argv) {
  printf("This program is well-written, so why don't use this unsuspicious header?\n");

  some_func();

  return 0;
}

For given example GCC will print following error:

error: format ‘%d’ expects a matching ‘int’ argument [-Werror=format=]

Luckily, we can use GCC diagnostic pragmas to suppress warnings for certain fragments of code this way

#include <stdio.h>

/* Begin of warning-less fragment */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
#include "bad_header.h"
#pragma GCC diagnostic pop
/* End of warning-less fragment */

int main(int argc, char **argv) {
  printf("This program is well-written, so why don't use this unsuspicious header?\n");

  some_func();

  return 0;
}

However, this code is not portable, so I recommend to add some checks to make sure this code can be compiled with older compilers, clang and others. I did a little research and had found out that these pragmas were introduced in GCC 4.5, so we can check it this way:

#include <stdio.h>

#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 5 ))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
#endif
#include "bad_header.h"
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 5 ))
#pragma GCC diagnostic pop
#endif

int main(int argc, char **argv) {
  printf("This program is well-written, so why don't use this unsuspicious header?\n");

  some_func();

  return 0;
}

It looks pretty ugly, but it's still much better than repairing whole header to avoid all the warnings.

Refer to GCC docs for more details on diagnostic pragmas


Back