Reputation: 1098
I would like to disable specific known warnings in C++ code coming from a library header when compiling my own code. There are clang and gcc specific methods for disabling the warnings. The way this is done is almost identical.
For clang:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-local-typedefs"
#include <library.h>
#pragma clang diagnostic pop
For gcc:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <library.h>
#pragma GCC diagnostic pop
Is there a clean way to suppress these warnings that is portable across clang and GCC?
Upvotes: 15
Views: 3149
Reputation: 132128
Well, clean is a relative term, but here is the approach we take in the testing code for this C library, which is intended to support all of GCC, clang and MSVC. As @Thomas mentions, _Pragma(GCC Whatever)
works with clang as well, so we can use that.
The general mechanism:
// Multi-compiler-compatible local warning suppression
#if defined(__GNUC__) || defined(__clang__)
#define DO_PRAGMA(X) _Pragma(#X)
#define DISABLE_WARNING_PUSH DO_PRAGMA(GCC diagnostic push)
#define DISABLE_WARNING_POP DO_PRAGMA(GCC diagnostic pop)
#define DISABLE_WARNING(warningName) DO_PRAGMA(GCC diagnostic ignored #warningName)
#elif defined(_MSC_VER)
#define DISABLE_WARNING_PUSH __pragma(warning( push ))
#define DISABLE_WARNING_POP __pragma(warning( pop ))
#define DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber ))
#else
// unknown compiler, ignoring suppression directives
#define DISABLE_WARNING_PUSH
#define DISABLE_WARNING_POP
#endif
Macros for disabling specific warnings:
#if defined(__GNUC__) || defined(__clang__)
// specific disable's for the warnings we care about
#define DISABLE_WARNING_PRINTF_FORMAT DISABLE_WARNING(-Wformat)
#define DISABLE_WARNING_PRINTF_FORMAT_EXTRA_ARGS DISABLE_WARNING(-Wformat-extra-args)
#if defined(__clang__)
#define DISABLE_WARNING_PRINTF_FORMAT_OVERFLOW
#define DISABLE_WARNING_PRINTF_FORMAT_INVALID_SPECIFIER DISABLE_WARNING(-Wformat-invalid-specifier)
#else
#define DISABLE_WARNING_PRINTF_FORMAT_OVERFLOW DISABLE_WARNING(-Wformat-overflow)
#define DISABLE_WARNING_PRINTF_FORMAT_INVALID_SPECIFIER
#endif
#elif define(_MSC_VER)
// TODO: Need to actually determine the appropriate MSVC warning numbers :-(
#define DISABLE_WARNING_PRINTF_FORMAT
#define DISABLE_WARNING_PRINTF_FORMAT_EXTRA_ARGS
#define DISABLE_WARNING_PRINTF_FORMAT_OVERFLOW
#define DISABLE_WARNING_PRINTF_FORMAT_INVALID_SPECIFIER
#else
// unknown compiler
#define DISABLE_WARNING_PRINTF_FORMAT
#define DISABLE_WARNING_PRINTF_FORMAT_EXTRA_ARGS
#define DISABLE_WARNING_PRINTF_FORMAT_OVERFLOW
#define DISABLE_WARNING_PRINTF_FORMAT_INVALID_SPECIFIER
#endif
In your program, you wrap the individual instructions, or blocks, as follows:
DISABLE_WARNING_PUSH
DISABLE_WARNING_PRINTF_FORMAT
DISABLE_WARNING_PRINTF_FORMAT_EXTRA_ARGS
DISABLE_WARNING_PRINTF_FORMAT_INVALID_SPECIFIER
sprintf_(buffer, "%.4.2s", "123456");
DISABLE_WARNING_POP
Upvotes: 3