使用功能测试宏和 Clang 时如何避免有关 c++Future-extensions 的警告?

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

我有一些针对 C++14 的代码可以使用 C++17 的 [[nodiscard]] 属性。使用功能测试宏来完成这个对我来说似乎很自然:

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

struct NODISCARD SomeType {};

然而,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

这很烦人,因为我已经适当地验证了即使我们在 C++14 模式下编译也存在 C++17 功能。我不想关闭 -Wc++17-extensions,但我需要抑制警告的这种特殊情况。

有没有一种在 Clang 中使用功能测试宏来避免这些警告的好方法? 或者是否有一种好方法可以仅针对这些我已经确认没问题的情况来抑制警告?

您可以使用 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 {};