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

问题描述

我有一些针对 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++17 特性存在,即使我们在 C++14 模式下编译。我不想关闭 -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 {};