I\'m finding __attribute__ ((warn_unused_result)) to be very useful as a means of encouraging developers not to ignore error codes returned by functions, but I
I think the SAL annotation which others have mentioned is the right answer for MSVC, but I'm guessing some people will be interested in more portability than just MSVC, GCC, and GCC-compatible compliers, so…
First off, GCC only supports warn_unused_result since 3.4. You may
want to check the values of __GNUC__ / __GNUC_MINOR__ instead of
just checking if __GNUC__ is defined, although at this point I have
trouble imagining anyone using a version of GCC older than 3.4.
Several compilers support the GCC-style function attribute, and may or
may not define __GNUC__ and friends:
__has_attribute(warn_unused_result)), and
compilers based on it (emscripten, xlc 13+, armclang, etc.), though
AFAIK it always masquerades as at least GCC 4.2, so you probably
don't need an explicit check.__GNUC__ (see the -no-gcc flag). I
don't know when they started supporting it (their documentation is
severely lacking), but I know 16.0+ is safe.__TI_GNU_ATTRIBUTE_SUPPORT__ will be defined when it is.Additionally, C++17 adds a [[nodiscard]] attribute. For versions of
GCC/clang which support [[nodiscard]] in C++17 mode you can also use
[[gnu::nodiscard]] in C++11 and greater mode, but if you're hiding
it behind a macro anyways I don't see a reason to do so instead of
just using __attribute__((__warn_unused_result__)).
Putting it together, there is a HEDLEY_WARN_UNUSED_RESULT macro in Hedley which looks like:
#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_) /* SAL */
# define HEDLEY_WARN_UNUSED_RESULT _Check_return_
#else
# define HEDLEY_WARN_UNUSED_RESULT
#endif
You should be able to strip out the internal Hedley macros and just copy the logic without too much trouble if you don't want to use Hedley (it's public domain / CC0). If you choose to do so you should probably base your port off the version in the repo as I'm far less likely to remember to keep this answer up to date with new information.