现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

VS2005中检测和更正 C/C++ 代码缺陷

2012-07-01 23:45 工业·编程 ⁄ 共 3667字 ⁄ 字号 暂无评论

VS2005中提供的检测方法:
1 IDE(集成开发环境)集成
2 #pragma 支持
3 批注支持
4 作为签入策略的一部分运行分析工具
5 Team System 与 Team Build 的集成
6 命令行支持

一 代码分析工具用于检测常见的编码错误,例如缓冲区溢出、内存未初始化、空指针取消引用,以及内存和资源泄露。

为 C/C++ 代码启用代码分析
在 Visual Studio 中打开一个项目。

在“项目”菜单上单击“属性”。

单击“代码分析”。

在“启用 C/C++ 代码分析”列表中,选择“是(/analyze)”,然后单击“确定”。

禁用 C/C++ 代码分析
在 Visual Studio 中打开一个项目。

在“项目”菜单上单击“属性”。

单击“代码分析”。

在“启用 C/C++ 代码分析”列表中,选择“否”,然后单击“确定”。

二 若要管理警告状态,请在单独的头文件中列出所有代码分析警告。将头文件包括在源文件中。使用 warning pragma 重写头文件中的设置。

启用或禁用代码分析警告
创建一个头文件,其中列出所有代码分析警告和这些警告的初始状态,如下面的代码所示:

// WarningState.h
   #pragma warning ( enable : 6001 )
   #pragma warning ( disable : 6011 )
// more warnings here
// end of file
将 WarningState.h 包括在应用程序头文件中。在本例中,MyApplication.h 代表头文件。

// MyApplication.h file
   #include "WarningState.h"
// ...
// end of file
将 MyApplication.h 文件包括在源代码文件中。在本例中,MyApplication.cpp 代表源文件。

// MyApplication.cpp file
#include "MyApplication.h"
若要修改警告状态,请在 .cpp 文件中使用 pragma 警告说明符,如下面的代码所示:

#pragma warning ( enable : 6011 )
#pragma warning ( disable : 6001 )    
三 若要在 C++ 中批注代码,必须首先包括 SourceAnnotations.h 文件,然后使用 vc_attributes 命名空间。(其他的批注属性:http://msdn2.microsoft.com/zh-cn/library/ms182037(VS.80).aspx)
在 C++ 中批注代码
向项目头文件添加 #include <CodeAnalysis/SourceAnnotations.h> 文件。             
然后,添加 using namespacevc_attributes; 语句。
示例
添加要包括的文件和命名空间后,批注 C++ 代码,如下面的代码所示:       
// MyCode.h
#include <CodeAnalysis/SourceAnnotations.h>
using namespace vc_attributes;
class CMyClass
{
public:
       void f ( [Pre ( Valid = Yes )] int *pWidth );
// code ...
};

// MyCode.cpp
#include "MyCode.h"
void CMyClass::f ( [Pre (Valid = Yes)] int pWidth )
{
}
在 C 中,必须对枚举属性值使用 SA_ 前缀。在 C++ 中,SA_ 前缀是可选的。

四 您可以在“错误列表”或输出窗口中查看代码分析警告。在“错误列表”中,可以对警告排序,并通过双击警告在代码编辑器中来查看导致该警告的代码行。也可以选择一个警告,然后按 F1 以查看该警告的帮助信息。
(C/C++ 代码分析警告:http://msdn2.microsoft.com/zh-cn/library/a5b9aa09(VS.80).aspx)
查看代码分析警告

在“视图”菜单上指向“其他窗口”,然后选择“错误列表”。

五 本演练演示如何通过使用 C/C++ 代码分析工具来分析 C/C++ 代码以查找潜在的代码缺陷。

演练:对 C/C++ 代码进行缺陷分析  (实例下载: http://msdn2.microsoft.com/zh-cn/library/ms182029(VS.80).aspx)

在本演练中,逐步完成使用代码分析来分析 C/C++ 代码以查找潜在代码缺陷的过程。

您将完成下列步骤:

在本机节点上运行代码分析。

分析代码缺陷警告。

将警告视为错误。

批注源代码以改进代码缺陷分析。

先决条件

Visual Studio 2005 Team System。

演示示例的副本。

对 C/C++ 进行基本了解。

对本机代码运行代码缺陷分析

在 Visual Studio 2005 Team System 中打开演示解决方案。

演示解决方案现在将出现在解决方案资源管理器中。

在“生成”菜单上单击“重新生成解决方案”。

将生成解决方案,并且不出现任何警告或错误。

在解决方案资源管理器中,选择 CodeDefects 项目。

在“项目”菜单上单击“属性”。

将显示“CodeDefects 属性页”对话框。

单击“代码分析”。

从“启用 C/C++ 代码分析”下拉列表中,选择“是(/analyze)”,然后单击“确定”。

重新生成 CodeDefects 项目。

代码分析警告显示在输出窗口中。

分析代码初始化缺陷警告

在“视图”菜单上单击“错误列表”。

取决于您在 Visual Studio 2005 Team System 中选择的开发人员配置文件,您可能需要指向“视图”菜单上的“其他窗口”,然后单击“错误列表”。

在“错误列表”中双击下列警告:

警告 C6230:语义不同的类型之间的隐式强制转换: 在 Boolean 上下文中使用 HRESULT。

代码编辑器显示导致在函数 boolProcessDomain() 中出现警告的代码行。该警告指示“if”语句中正在使用 HRESULT,而原本应使用布尔值结果。

通过使用 SUCCEEDED 宏来更正该警告。代码看起来应类似下面这样:

if (SUCCEEDED (ReadUserAccount()) )
在“错误列表”中双击下列警告:

警告 C6282:运算符不正确: 在测试上下文中执行了常数赋值。Was == intended?(事实是否确实像预计的那样?)

通过测试是否等同来更正该警告。代码看起来应类似下面这样:

if ((len == ACCOUNT_DOMAIN_LEN) || (g_userAccount[len] != '\\'))
将警告视为错误

在 Bug.cpp 文件中,将下面的 #pragma 语句添加到文件的开头,将警告 C6001 视为错误:

#pragma warning (error: 6001)
重新生成 CodeDefects 项目。

在“错误列表”中,C6001 现在显示为一个错误。

通过将 i 和 j 初始化为 0,更正“错误列表”中的其余两个 C6001 错误。

重新生成 CodeDefects 项目。

将生成项目,并且不出现任何警告或错误。

更正 annotation.c 中的源代码批注警告

在解决方案资源管理器中,选择 Annotations 项目。

在“项目”菜单上单击“属性”。

将显示“Annotations 属性页”对话框。

单击“代码分析”。

从“启用 C/C++ 代码分析”下拉列表中,选择“是(/analyze)”,然后单击“确定”。

重新生成 Annotations 项目。

在“错误列表”中双击下列警告:

警告 C6011:正在取消 NULL 指针“newNode”的引用。

该警告指示调用方检查返回值失败。在这种情况下,调用 AllocateNode 可能会返回一个 NULL 值(有关 AllocateNode 的函数声明,请参见 annotations.h 头文件)。

打开 Annotation.c 文件。

若要更正该警告,请使用“if”语句来测试返回值。代码看起来应类似下面这样:

if (NULL != newNode)

{

newNode->data = value;

newNode->next = 0;

node->next = newNode;

}

重新生成 Annotations 项目。

将生成项目,并且不出现任何警告或错误。

使用源代码批注

通过使用 Pre 和 Post 条件,批注函数 AddTail 的形参和返回值,如下面的示例所示:

[SA_Post (Null=SA_Maybe)] LinkedList* AddTail

(

[SA_Pre(Null=SA_Maybe)] LinkedList* node,

int value

)

重新生成 Annotations 项目。

在“错误列表”中双击下列警告:

警告 C6011:正在取消 NULL 指针“node”的引用。

该警告指示传递给函数的节点可能为空。

若要更正该警告,请使用“if”语句来测试返回值。代码看起来应类似下面这样:

  . . .
  LinkedList *newNode = NULL;
  if (NULL == node)
  {
       return NULL;
      . . .
  }
重新生成 Annotations 项目。

将生成项目,并且不出现任何警告或错误。

给我留言

留言无头像?