Search code examples
c++compiler-warningsclang++suppress-warnings

How do I avoid warnings about c++Future-extensions when using feature test macros and Clang?


I have some code targetting C++14 which could make use of C++17's [[nodiscard]] attribute. It seemed natural to me to use feature-test macros to accomplish this:

#ifdef __has_cpp_attribute
#   if __has_cpp_attribute(nodiscard)
#       define NODISCARD [[nodiscard]]
#   else
#       define NODISCARD
#   endif
#else
#   define NODISCARD
#endif

struct NODISCARD SomeType {};

However, Clang "helpfully" warns me that I'm using a feature that doesn't exist until C++17:

<source>:12:8: warning: use of the 'nodiscard' attribute is a C++17 extension [-Wc++17-extensions]
struct NODISCARD SomeType {};
       ^
<source>:3:28: note: expanded from macro 'NODISCARD'
#       define NODISCARD [[nodiscard]]
                           ^
1 warning generated.
Compiler returned: 0

This is quite annoying, as I have appropriately verified that the C++17 feature exists even if we're compiling in C++14 mode. I don't want to turn off -Wc++17-extensions, but I need to suppress this particular case of the warning.

Is there a good way to use feature-test macros with Clang that avoids these warnings? Or is there a good way to suppress the warnings just for these cases where I've verified that it's okay?


Solution

  • You can temporarily disable diagnostics with the pragma clang diagnostic:

    #ifdef __has_cpp_attribute
    #   if __has_cpp_attribute(nodiscard)
    #       ifdef __clang__
    #           define NODISCARD \
                    _Pragma("clang diagnostic push") \
                    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
                    [[nodiscard]] \
                    _Pragma("clang diagnostic pop")
    #       else
    #           define NODISCARD [[nodiscard]]
    #       endif
    #   endif
    #endif
    
    #ifndef NODISCARD
    #    define NODISCARD
    #endif
    
    struct NODISCARD SomeType {};