我认为其他人提到的SAL注释是MSVC的正确答案,但我猜有些人会对比MSVC、GCC和兼容GCC编译器更感兴趣的可移植性...
首先,GCC只支持自3.4以来的"warn_unused_result"。您可能希望检查__GNUC__/__GNUC_MINOR__的值,而不仅仅是检查是否定义了__GNUC__,尽管此时我很难想象有人使用早于3.4版本的GCC。
多个编译器支持GCC风格的函数属性,并且可能或可能不定义__GNUC__和相关内容:
- Clang(使用
__has_attribute(warn_unused_result)
检查),以及基于它的编译器(emscripten,xlc 13+,armclang等),虽然我知道它总是伪装成至少GCC 4.2,所以你可能不需要明确检查。
- 英特尔并不总是定义
__GNUC__
(请参见-no-gcc
标志)。我不知道他们何时开始支持它(他们的文档严重缺乏),但我知道16.0+是安全的。
- TI 8.0+支持它
- 当传递--gcc时,TI 7.3+支持它;当它被定义时,
__TI_GNU_ATTRIBUTE_SUPPORT__
将被定义。
- Oracle Developer Studio 12.6+在C++模式下支持它,但不支持C。
- PGI在C++模式下支持它。据我所知,它没有记录,所以我不确定它是何时添加的(它是#1650-D),但它肯定存在于17.10+中。在C模式下静默忽略它,希望他们有一天会实现它。
此外,C++17 添加了一个
[[nodiscard]]
属性。对于支持 C++17 模式下的
[[nodiscard]]
的 GCC/clang 版本,您也可以在 C++11 及更高版本中使用
[[gnu::nodiscard]]
,但如果您只是将其隐藏在宏后面,我认为没有理由这样做,而不是简单地使用
__attribute__((__warn_unused_result__))
。
将其放在一起,
Hedley 中有一个
HEDLEY_WARN_UNUSED_RESULT 宏,看起来像:
#if defined(__cplusplus) && (__cplusplus >= 201703L)
# define HEDLEY_WARN_UNUSED_RESULT [[nodiscard]]
#elif \
HEDLEY_GNUC_HAS_ATTRIBUTE(warn_unused_result,3,4,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
(HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
HEDLEY_PGI_VERSION_CHECK(17,10,0)
# define HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#elif defined(_Check_return_)
# define HEDLEY_WARN_UNUSED_RESULT _Check_return_
#else
# define HEDLEY_WARN_UNUSED_RESULT
#endif
你应该能够轻松地剥离掉内部的 Hedley 宏,只需复制逻辑即可,如果你不想使用 Hedley(它是公共领域/CC0)。如果你选择这样做,你应该基于仓库中的版本进行移植,因为我很少会记得更新这个答案的新信息。