pragma ignored in g++ and clang
Asked Answered
T

1

14

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?

Thermionic answered 23/2, 2015 at 18:59 Comment(7)
These pragmas suppress completely different diagnostics.Kommunarsk
I edited the post so that they suppress the same thing.Thermionic
Why can't you use #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
Clang also recognizes #pragma GCC, so just use #pragma GCC if you want to be portable. Your link even mentions that...Gully
The typical solution is to define MACROs to suppress these warnings using _Pragma. Other answers on stackoverflow already show how to do this. clang and gcc understand _Pragma, MSVC requires __pragma (MSVC 16.6 with /Zc:preprocessor also understand _Pragma.Timbre
Why not just optionally remove problematic option in Makefile depending on compiler version?Ashlynashman
M
0

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
Malleable answered 21/8 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.