Tim
Tim

Reputation: 1098

pragma ignored in g++ and clang

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

Answers (1)

einpoklum
einpoklum

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 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 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

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

Upvotes: 3

Related Questions