代码之家  ›  专栏  ›  技术社区  ›  Paul R

msvc相当于属性(警告未使用的结果))?

  •  22
  • Paul R  · 技术社区  · 14 年前

    我在找 __attribute__ ((warn_unused_result)) 作为鼓励开发人员不要忽略函数返回的错误代码的一种非常有用的方法,但是我需要它与MSVC以及GCC和GCC兼容的编译器(如ICC)一起工作。微软VisualStudioC/C++编译器有一个等价的机制吗?(到目前为止,我已经尝试过在msdn中涉水而没有任何运气。)

    5 回复  |  直到 7 年前
        1
  •  13
  •   Albert    11 年前

    它是 _Check_return_ . 见 here 类似注释和 here 功能行为。自MSVC 2012年起提供支持。

    例子:

    _Check_return_
    int my_return_must_be_checked() {
        return 42;
    }
    
        2
  •  8
  •   Paul R    11 年前

    MSVC 2012及更高版本的更新

    非常感谢@albert指出MSVC现在支持注释 _Check_return_ 从使用SAL静态代码分析时的Visual Studio 2012起。我添加这个答案是为了包含一个对其他人有用的跨平台宏:

    #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,则切换等效项。这也会在一定程度上降低构建速度。

        3
  •  5
  •   Community CDub    8 年前

    VisualStudio的某些版本随以前调用的静态分析工具一起打包 PREFast (现在简称为“C/C++代码分析”)。Precast使用注释来标记代码。其中一个注释, MustCheck 做你想要的。

        4
  •  3
  •   Timo Geusch    14 年前

    据我所知,MS编译器没有等效的pragma或属性——您可以得到的唯一“未使用”类型警告是,当您使用适当的警告级别打开优化器时,变量的警告。

        5
  •  1
  •   nemequ    7 年前

    我认为其他人提到的SAL注释是正确的。 回答MSVC,但我想有些人会感兴趣的 比MSVC、GCC和GCC兼容的编译器更具可移植性, 所以

    首先,GCC只支持 warn_unused_result 从3.4开始。你 可以 想要检查的值 __GNUC__ / __GNUC_MINOR__ 而不是 只是检查一下 _ GNUC公司__ 是有定义的,尽管在这一点上 无法想象任何使用3.4以上版本的gcc的人。

    几个编译器支持gcc-style函数属性,可以 可能无法定义 _ GNUC公司__ 和朋友们:

    • 叮当声(检查 __has_attribute(warn_unused_result) ) 不过,基于它的编译器(emscripten、xlc 13+、armclang等) 阿法克,它总是伪装成至少GCC4.2,所以你可能 不要 需要 明确的检查。
    • 英特尔并不总是定义 _ GNUC公司__ (参见 -no-gcc 标志)。我 不知道他们什么时候开始支持它(他们的文档是 严重缺乏),但我知道16.0+是安全的。
    • Ti 8.0+支持它
    • Ti7.3+在通过GCC时支持它; __TI_GNU_ATTRIBUTE_SUPPORT__ 将在其存在时定义。
    • Oracle DeaveStudio Studio 12.6 +支持C++模式 though not C .
    • 在C++模式下它支持它。因为它没有文件,所以我没有 当然,当它被添加时(它是1650-D),但它确实存在 在17.10+中。在C模式下,它被静默地忽略了,希望他们会 总有一天会实现它。

    另外,C++ 17添加了 [[nodiscard]] 属性。对于版本 支持的GCC/Clang [节点卡]] 在C++ 17模式中你也可以使用 [[gnu::nodiscard]] 在C++ 11和更大的模式下,但是如果你在隐藏 不管怎么说,在宏的背后,我没有看到这样做的理由,而不是 只是使用 __attribute__((__warn_unused_result__))

    把它放在一起,有一个 HEDLEY_WARN_UNUSED_RESULT 宏输入 Hedley 看起来像:

    #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)。如果你选择这样做,你应该 可能你的端口是基于repo中的版本,因为我要少得多。 可能会记住用新的 信息。