我发现__attribute__ ((warn_unused_result))
非常有用,可以鼓励开发人员不要忽略函数返回的错误代码,但是我需要这个来处理MSVC以及gcc和gcc兼容的编译器,比如ICC。 Microsoft Visual Studio C / C ++编译器是否具有等效机制? (到目前为止,我已经尝试过通过MSDN而没有任何运气。)
答案 0 :(得分:13)
这是_Check_return_
。有关类似注释的示例,请参阅here;有关函数行为,请参阅here。自MSVC 2012以来,它得到了支持。
示例:
_Check_return_
int my_return_must_be_checked() {
return 42;
}
答案 1 :(得分:8)
非常感谢@Albert指出,当使用SAL静态代码分析时,MSVC现在支持Visual Studio 2012中的注释_Check_return_
。我正在添加这个答案,以便我可以包含一个对其他人有用的跨平台宏:
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define CHECK_RESULT __attribute__ ((warn_unused_result))
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#define CHECK_RESULT _Check_return_
#else
#define CHECK_RESULT
#endif
请注意,与gcc 等不同,(a)MSVC要求对函数的声明和定义进行注释,并且(b)注释需要在声明/定义的开头(gcc允许)。因此通常需要使用例如:
// foo.h
CHECK_RETURN int my_function(void); // declaration
// foo.c
CHECK_RETURN int my_function(void) // definition
{
return 42;
}
另请注意,如果从命令行进行编译,则需要/analyze
(或-analyze
)开关,如果使用Visual Studio IDE,则需要等效。这也有助于减缓构建速度。
答案 2 :(得分:5)
VisualStudio的某些版本附带了一个静态分析工具,以前称为PREFast(现在简称为“C / C ++代码分析”)。 PREFast使用注释来标记代码。其中一个注释MustCheck可以满足您的需求。
答案 3 :(得分:3)
据我所知,MS编译器没有等效的编译指示或属性 - 当您使用适当的警告级别打开优化器时,可以获得的唯一“未使用”类型警告是变量。
答案 4 :(得分:1)
我认为其他人提到的SAL注释是正确的 回答MSVC,但我猜测有些人会对此感兴趣 比MSVC,GCC和GCC兼容的编译器更具可移植性, 所以...
首先,自3.4以来,GCC仅支持warn_unused_result
。你可能
想要检查__GNUC__
/ __GNUC_MINOR__
的值,而不是
只是检查是否定义了__GNUC__
,尽管此时我已经定义了__GNUC__
很难想象有人使用的是超过3.4的GCC版本。
有几个编译器支持GCC样式的函数属性,可能或
可能无法定义__has_attribute(warn_unused_result)
和朋友:
__GNUC__
核对),和
但是,基于它的编译器(emscripten,xlc 13+,armclang等)
AFAIK它总是伪装成至少GCC 4.2,所以你可能
不要需要明确检查。-no-gcc
(请参阅__TI_GNU_ATTRIBUTE_SUPPORT__
标志)。一世
不知道他们什么时候开始支持它(他们的文件是
严重缺乏),但我知道16.0+是安全的。[[nodiscard]]
将被定义。此外,C ++ 17添加了[[nodiscard]]
属性。对于版本
在C ++ 17模式下支持[[gnu::nodiscard]]
的GCC / clang也可以使用
在C ++ 11及更高版本模式下__attribute__((__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_WARN_UNUSED_RESULT中有一个Hedley宏看起来像:
document.querySelector('a[rel="Spanish"]')
你应该能够剥离内部的Hedley宏而且只是 如果你不想使用,复制逻辑没有太多麻烦 Hedley(它的公共领域/ CC0)。如果你选择这样做,你应该这样做 可能是基于你在回购中的版本的端口,因为我更少 可能要记住用新的答案保持这个答案是最新的 信息。