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 pile of macros
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 disaabling 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
Example usage
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
#if
conditionals? – Tecumseh#if
conditionals are an option, but on what conditions? Do I just special case each compiler using a predefined macro every time I want to suppress a specific warning? – Thermionic#pragma GCC
, so just use#pragma GCC
if you want to be portable. Your link even mentions that... – Gully