Visual Studio 2017 提高 C++ 核心检查
C++ Core Check improvements in Visual Studio 2017 15.5 [原文发表时间]: 2017年11月15日,[作者]: Sergiy OryeKhov
对于本机代码静态分析工具,我们已经在Visual Studio 2017 15.5 预览版 4上进行了C++ 核心准则检查 扩展。自从15.3 以来大部分工作都集中在新的规则,这将帮助开发者开始编写安全的C++新项目,而那些使用旧版开发的项目可以被移去更安全的现代C++。对于刚开始使用核心准则的人,我们建议您去查看工作草案的最新版本:“C++ 核心准则检查”。
这篇文章是关于在VS2017 15.5 上改变的概述。有关当前发布版的更多信息,请参阅docs.microsoft.com 上受支持的规则集列表。
注意docs.microsoft.com上的一些链接还尚未解决。不是所有的官方的文档都是为这个话题编写的。
新的规则集
在之前的发布版本中我们引入几个新的规则集以允许客户可以缩减代码分析结果。对15.5 这个规则的实施扩展了一些已经存在的规则集(原始指针,所有者指针,唯一指针,类型),也引入了一些新的类目:
- 类规则:本节包含了一些主要关注使用特殊方法和虚拟规范的规则。这是一个为类和类层次检查建议的一个子集。
- 并行规则:这当前包含一个单一的规则,可以捕获严重的声明守卫对象。更多的信息请参照 C++ 核心准则中相关的并行规则。
- 声明规则:这是一组来自接口准则的规则,这关注的是如何声明一个全局的变量。
- 函数规则:这两个检查有助于采用noexpect 说明符。这是清晰的功能设计和执行准则的一部分。
- 共享指针规则:作为资源管理准则执行的一部分,我们添加了一些特定的用于如何将共享指针传递到函数或者本地使用的规则。
- 风格规则:在这次发布中我们有一个简单但是很重要的检查就是禁止使用goto。这是在C++中提高代码风格和表达式与语句使用的第一步。尽管这是被期待的在C++ 核心准则下的goto语句,正确使用这个结构是罕见的,他值得去审查。
每一套新规则
- 类规则
- C26432 DEFINE_OR_DELETE_SPECIAL_OPS 特殊的操作(例如:析构函数和拷贝构造函数)意味着特殊的行为,并且应该全套的定义这种行为。
- C26436 NEED_VIRTUAL_DTOR 虚拟方法有一种多态的行为,这需要对对行清理进行更细致的管理。
- C26434 DONT_HIDE_METHODS通过名称隐藏方法就像隐藏变量一样。名称不应该出现歧义。
- 并行规则
- C26441 NO_UNNAMED_GUARDS保护对像是分配给具有适当范围的局部变量,并且永远不会作为临时变量离开。这个规则主要针对一些常见的滥用案例在 CPPCon 2017: 路易斯·布兰迪“好奇地重复C++的错误在feedbook”。
- 声明规则
- C26426 NO_GLOBAL_INIT_CALLS从初始化程序中调用一个全局的变量,可能会导致一个不被期待的结果,由于初始化的顺序不确定。
- C26427 NO_GLOBAL_INIT_EXTERNS 全局变量不应该被引用为一个外部符号以避免初始化的顺序问题。
- 函数规则
- C26439 SPECIAL_NOEXCEPT 一些特殊的函数(像析构函数)应该避免抛出异常。
- C26440 DECLARE_NOEXCEPT 如果一个函数没有抛出或者没有调用其他函数的可抛出的异常,那么它应该被标记作为无异常。
- 资源管理规则
- C26416 NO_RVALUE_REF_SHARED_PTR 通过rvalue-reference 去定义共享指针是没有必要的并且通常表示共享指针的滥用。使用共享指针传值是安全并且成本较低的。
- C26417 NO_LVALUE_REF_SHARED_PTR 通过引用传递的共享指针作为一个输出参数,它的所有权被更新在函数中是期待的(例如调用reset())。如果共享指针仅用于访问其包含的对象,则应该传递一个简单的引用或指向所包含的对象的指针。
- C26418 NO_VALUE_OR_CONST_REF_SHARED_PTR 当一个共享指针被传递给一个值或对const的引用时,它向调用者表明该函数需要控制其包含的对象的生存期而不影响调用代码。 但是,如果智能指针从不复制,移动或以其他方式修改,将影响包含对象的生存期,则应该传递一个简单的引用或指向所包含对象的指针。
- C26415 SMART_PTR_NOT_NEEDED 智能指针在资源管理上还是很方便的,但是当它们被使用仅用作访问其包含的对象时,代码可以通过传递简单的引用或者指针来包含对象。
- C26414 RESET_LOCAL_SMART_PTR 使用本地智能指针意味着需要控制包含对象的生命周期。 如果一个函数没有使用智能指针来传递函数以外的属性,并且没有明确的调用来改变所有权,那么应该使用堆栈分配的局部变量来避免不必要的堆分配。
- C26429 USE_NOTNULL如果一个指针被解引用但是没有测试过无效,那么使用gsl:not _null 是有用的 以至于它的有效性的假设是正确的。
- C26430 TEST_ON_ALL_PATHS如果一个指针在至少一个路径上被解引用或者测试,代码应该确保他在所有路径上被测试,因为测试意味着指针是空的。
- C26431 DONT_TEST_NOTNULL 测试gsl:not_null类型表达式的无效性显然是没有必要的。
- 风格规则
- C26438 NO_GOTO 现在C++不会使用goto语句在用户的编码中。
- 输入规则
- C26437 DONT_SLICE即使编译器允许使用默认的切片,但它是不安全的和不可维护的。
- C26472 NO_CASTS_FOR_ARITHMETIC_CONVERSION静态转换可以悄悄地丢掉那些不适合算数类型的数据。
- C26473 NO_IDENTITY_CAST 相同类型指针之间的转换显然是没有必要的。
- C26474 NO_IMPLICIT_CAST 在隐式完成指针转换的情况下,应该忽略转换。请注意,规则ID有点令人误解,应该将其解释为“在可接受的地方不使用默认的投射”。
- C26475 NO_FUNCTION_STYLE_CASTS函数风格转换是C风格转换的另一种新形式,可以导致无声的数据截断。
警告重新排列
VS2017 15.3 上出现的一些警告编号在15.5上将不可用。这些警告不再出现,但是被更多的特殊的检查代替。主要的目标是将警告中的特定常见模式分为单独的警告。
- C26461 USE_CONST_INPUT_ARGUMENTS被更多特定的警告代替。
- C26470 NO_REINTERPRET_CAST_TO_VOID_PTR已经被删除,并被两个新的警告的逻辑部分取代。同样C26490 NO_REINTERPRET_CAST已被缩减,仅覆盖未被这些新警告覆盖的情况。
- C26496 USE_CONST_FOR_VARIABLE 被缩小为非指针值;其余的被分为具体的警告:
- C26492 NO_CONST_CAST 被缩减为有效的转换;其他情况有特定的警告:
- C26491 NO_STATIC_DOWNCAST被缩小为不是多态的类型;多态类型的转换被用一个特定的警告标记:
最后
好的工具可以帮助你维护和升级你的代码。 C ++核心准则是一个很好的开始,C ++核心准则检查器可以帮助你清理你的代码并保持清洁。 尝试在Visual Studio 2017 15.5版中扩展的C ++核心指南检查器,并让我们知道您的想法。
对于我们如果您有任何的反馈或者建议,请让我们知道。我们可以通过下面的评论,邮件(visualcpp@microsoft.com)联系到。你也可以提供feedback通过 帮助->报告产品问题,或者通过开发者社区。您可以找到我们在Twitter(@VisualC) 和Facebook(msftvisualcpp)。