Я думаю, что аннотация SAL, о которой упоминали другие, является правильным ответом для MSVC, но я предполагаю, что некоторые люди будут заинтересованы в большей переносимости, чем просто MSVC, GCC и GCC-совместимые компиляторы, поэтому…
Во-первых, GCC поддерживает только warn_unused_result
, начиная с 3.4.Вы можете хотеть проверить значения __GNUC__
/ __GNUC_MINOR__
вместо того, чтобы просто проверять, определено ли __GNUC__
, хотя в этот момент у меня возникают проблемы с представлением кого-либо, использующего версию GCC старше 3.4.
Несколько компиляторов поддерживают атрибут функции в стиле GCC и могут определять или не определять __GNUC__
и друзей:
- Clang (проверьте с помощью
__has_attribute(warn_unused_result)
) и компиляторы на основеэто (emscripten, xlc 13+, armclang и т. д.), хотя AFAIK всегда маскируется под как минимум GCC 4.2, поэтому вам, вероятно, не требуется явная проверка. - Intel не делаетне всегда определяйте
__GNUC__
(см. флаг -no-gcc
).Я не знаю, когда они начали поддерживать его (их документации крайне не хватает), но я знаю, что 16.0+ безопасен. - TI 8.0+ поддерживает его
- TI 7.3+ поддерживает его, когда --gcc пройден;
__TI_GNU_ATTRIBUTE_SUPPORT__
будет определено, когда оно есть. - Oracle Developer Studio 12.6+ поддерживает его в режиме C ++, , но не C .
- PGI поддерживает его в режиме C ++.AFAICT, он недокументирован, поэтому я не уверен, когда он был добавлен (это # 1650-D), но он определенно присутствует в 17.10+.Он тихо игнорируется в режиме C, надеюсь, они когда-нибудь его реализуют.
Кроме того, C ++ 17 добавляет атрибут [[nodiscard]]
.Для версий GCC / clang, которые поддерживают [[nodiscard]]
в режиме C ++ 17, вы также можете использовать [[gnu::nodiscard]]
в режиме C ++ 11 и выше, но если вы все равно скрываете его за макросом, я не вижупричина сделать это вместо того, чтобы просто использовать __attribute__((__warn_unused_result__))
.
Соединяя его, есть макрос 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_) /* SAL */
# define HEDLEY_WARN_UNUSED_RESULT _Check_return_
#else
# define HEDLEY_WARN_UNUSED_RESULT
#endif
Вы должны быть в состоянии вырезать внутренние макросы Hedley и просто скопировать логику без особых проблем, если не хотите использовать Hedley (это общественное достояние / CC0).Если вы решите сделать это, вам, вероятно, следует основывать свой порт на версии, указанной в репозитории, поскольку я с гораздо меньшей вероятностью не забуду регулярно обновлять этот ответ новой информацией.