Pascal Analyzer 4 代码分析使用简要说明
概述
不管在那个开发团队中每个人的编写风格往往是千差万别能力也有高低,如何让别人快速看懂自己的代码维护你的代码。尽量避免不必要的简单错误,为编写代码作一定的约束是必不可少的。
如果你说我一个人不需要规范,其实不然。个人的代码风格能看出你的实际能力。犹如写文章一样杂乱有章,别人看都不愿意看,再精彩的故事也没用。日后自己维护也会头大。
因此有一份简单的代码编写约束是非常有必要的,不仅能提高可读性而且能提高代码质量。
1. 创建分析工程
打开软件后,有显示向导界面(默认关闭的,可以通过File菜单下的Run Wizard打开)在工程选择界面上选要分析的工程(如下图所示)
(图1)
选择工程后下一步,选择Delphi版本,选择后,在分析设置界面,我们可以选(Main File And Used Units),不用包括DFM文件,路径和条件设置界面中,可以把所有的选项都不选(这些可以在后面调整),选项确认后,会提示保存,可以选择保存(也可以不保存),选择后,工具进入分析阶段(需等一会儿),分析完,生成分析报告(如下图所示)
(图2)
也可以在进入界面后,直接新建工程(File菜单下的New Project 或工具条新建),新建后点击分析中的运行。
分析的工程文件(. dpr)不需要编译通过的,可以根据分析需要创建只包括需要分析的单元,这里要注意最好有工程同名的配置文件(.dof)。
2. 工程选项设置
在打开已有工程或新建工程后,选择工程属性(或通过New Project方式打开)
在这里需要关注的主要有:
a) 工程版本(Target version),该选项按实际情况选择(暂不确认对分析有什么影响)
b) 包含文件必须存在(Include Files must Exist),该选项可以不选(特别是有某些目录被排除的情况下,选择会导致分析报错并中断)
c) 使用工程设置(Use Delphi Project options if found),如果进行全工程分析时,可以选择此选择,选择此选项后,分析工具会使用工程中的搜索路径,分析的单元会很多。
d) Delphi环境路径(Append Delphi library path 和Browsing path)该选项建议不选。
e) 分析排除路径(Exclude search path),有设置时,分析工具将不分析排除路径下的单元,因工程经常会携带一下第3方的控件,这种情况下,把这些控件目录及子目录排除,会减少不必要的分析(注意排除路径可能不支持相对路径,最好使用绝对路径,或直接通过向导设置)。
3. 分析报告解读
该工具的分析报告内容比较多,根据一段时间的使用和分析,感觉以下分析项目意义较大:
Warnings(警告方面):
Interfaces passed as parameters without "const" directive(重要)
Constructors/destructors without calls to inherited(重要)
Interfaced identifiers that are used, but not outside of unit(一般)
Interfaced class identifiers that are public/published, but not used outside of unit(一般)
Possible bad object creation(一般)
Ambiguous references in with-blocks(一般)
Optimization(优化方面):
Missing "const" for unmodified string parameter(重要)
Local subprograms with references to outer local variables(一般)
Memory(内存方面):
Local objects with unprotected calls to Free(一般)
Code Reduction(代码精简方面):
Local identifiers that are set and referenced once(一般)
Local long strings that are initialized to empty string(一般)
Boolean assignment can be shortened(一般)
Convention Compliance(习惯约定方面)
Local identifiers that "shadow" outer scope identifiers(一般)
Inconsistent Case(大小写不一致方面)
Inconsistent case for same identifier(一般)
下面对这些关注方面进行简要说明,方便理解。
警告提示(Warnings)
重要关注方面
a) 不明确的引用关系(Ambiguous unit references)
该提示说明,使用的常量、函数、过程有重名现象,这些需要分析,尽量消除。
b) 接口类型参数未加const 声明(Interfaces passed as parameters without "const" directive)
function Save(ADB: IBaseDBIntf): Boolean; virtual;
接口作为参数传递,未加const 声明时,编译器在调用时 会加上 _AddRef 调用结束后会加上 _Release,这在频繁调用时会降低效率。
c) 解构/析构未继承调用(Constructors/destructors without calls to inherited)
如果类继承父类,解构时未继承调用可能会导致父类未初始化;析构时未继承调用可能会导致内存泄漏。类似的还包括(Destructors without override 未声明覆盖)。
d) 函数未设置返回值(Function result not set)
function TdlgInputHuanSuanLv.ActOkNotify: Boolean;
begin
DoOk;
end;
该情况Delphi编译时,通常也有警告提示,函数未设置返回值可能会导致不可预料的结果。
一般关注方面
a) 对外定义(包括类、函数等声明)被使用了,但只在本单元内(Interfaced identifiers that are used, but not outside of unit)
简单示例如function BoolToInt
function BoolToInt(ABoolValue: Boolean): Integer; implementation {$R *.dfm} function BoolToInt(ABoolValue: Boolean): Integer;
begin
Result := Integer(ABoolValue);
end; procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(IntToStr(BoolToInt(False)));
end;
这个提示可以列出一些不必要公布的函数或类,对这些函数或类进行一些分析后,可能会有新的归类和设计。
b) 对外公布类的公共属性和方法,只在本单元使用了(Interfaced class identifiers that are public/published, but not used outside of unit)
这个提示可以用来帮助精简对外公用的属性和方法
c) 危险的退出(Dangerous Exit-statements)
在一个过程、函数中,如果开头有Exit 就会提示该信息,这通常有两种情况:一是该过程不使用了,建议删除该过程;另一种是调试时增加的代码,但忘记删除了,这个需要确认核实。
d) 空的强制执行模块(Empty finally-block)
有该提示的 Try … finally结构可以删除,提高代码效率。
e) 可能是错误类创建过程(Possible bad object creation)
procedure Proc;
var
Bmp : TBitmap;
begin
Bmp.Create; //错误
end;
procedure Proc2;
begin
TNode.Create(Parent);//内存泄漏
end;
有这样提示的代码可能或导致错误或内存泄漏。
f) 危险的块声明引用(Ambiguous references in with-blocks)
procedure TForm1.Button1Click(Sender: TObject);
begin
with Button1 do
begin
Caption := 'test';
end;
end;
这种提示通常发生在 块定义的类实例和过程所属的类有同名的属性或过程(如上图代码 Caption),这在复杂逻辑中往往会导致问题。
优化建议(Optimization)
重要关注方面
a) 未发生修改的字符串参数未声明为const (Missing "const" for unmodified string parameter)
function LoadSQL(ACondition: string; AOnlyStruct: Boolean = False):
因字符串有引用计数,在明确知道不需要修改的字符串参数前,请加上 const,这样可以提高效率。类似的参数还有 record、array、Interface等。
一般关注方面
a) 子过程使用过程外的变量(Local subprograms with references to outer local variables)
procedure TSelectTextHelper.InitFields(AFields: TSerializableFields; AItem: TSerializeItem);
var
i: Integer;
aField: TSerializableField;
procedure InnerAddField(AIdx: Integer);
begin
aField := TSerializableField(AFields.Append);
aField.FieldName := aField.FieldItem.ClassFieldName;
aField.DataType := TypeKindToFieldType(aField.FieldItem.DataType);
end;
begin
AFields.Clear;
if AItem <> nil then
begin
i := AItem.ObjFieldsMap.IndexByName(AItem.KeyField);
InnerAddField(i);
end;
end;
如上面的代码所示,子过程使用外面的 aField,这种情况需要尽量避免(特别是影响效率的代码段),建议子过程尽量放在 变量声明前面。
内存建议(Memory)
一般关注方面
a) 过程内的对象未在保护结构内释放(Local objects with unprotected calls to Free)
var
aList: TList;
begin
aList := TList.Create;
;//省略逻辑过程
aList.Free;
对象释放过程没有在保护结构时,如果释放前有异常抛出或提前退出时,会导致内存泄漏,建议释放过程尽量使用 try … finall结构。
b) 不对称的创建释放(Unbalanced Create/Free)
procedure LocalProc;
var
Obj: TMyClass;
begin
Obj := TmyClass.Create;
Obj.DoSomething;
end;
不对称释放,往往会导致内存泄漏,但分析工具对一些加入列表的、全局对象等判断不够,导致很多误报。另外还有下面这种情况也不提倡使用,最好把返回对象作为参数传入,这样可能避免疏忽引起的泄漏
function TForm1.GetList: TStringList;
begin
;//省略逻辑
Result := TStringList.Create;
end;
//建议改成
procedure TForm1.GetList(Alist: TstringList);
begin
;//省略逻辑
end;
代码精简建议(Code Reduction)
一般关注方面
a) 过程内本地变量只使用一次(Local identifiers that are set and referenced once)
var
aData: TSearchResult_Data;
begin
if FDataList <> nil then
begin
aData := TSearchResult_Data(FDataList.Items[AIndex]);
if not aData.Valid then
Value := cst_Invalid_Price;
end;
end; //可精简为
begin
if FDataList <> nil then
begin
if not TSearchResult_Data(FDataList.Items[AIndex]).Valid then
Value := cst_Invalid_Price;
end;
end;
不在循环体内的只使用一次的变量往往可以精简,如上图,这种情况要具体情况具体分析,有很多时候,分析报告这方面的提示是不正确的。类似的还有Local identifiers that possibly are set and referenced once,这里不另外列举。
b) 过程内字符串变量初始化为空(Local long strings that are initialized to empty string)
var
s: string;
begin
s := '';
;//省略逻辑
如上例所示,s设置为空是没有必要的,编译器已经自动初始化了。
c) 布尔赋值可以更精简(Boolean assignment can be shortened)
if CheckedCount > 0 then
NewState := True
else
NewState := False; //可以精简为
NewState := CheckedCount > 0;
该类提示往往是代码使用了条件判断再赋值的方式,该类代码可以优化另外也可以关注(Unneeded boolean comparisons)。
习惯约定建议(Convention Compliance)
一般关注方面
a) 参数重名情况Local identifiers that "shadow" outer scope identifiers
procedure TfrmMessageDlg.showButton(flags, timeCount: Integer); function GetButtons(Flags: integer): TMsgDlgButtons;
begin
;//省略逻辑
end; begin
;//省略逻辑
end;
该情况一般发生在过程下有子过程中,如上面的代码所示,建议不要重名现象,重名会导致易读性下降。
大小写不一致建议(Inconsistent Case)
一般关注方面
a) 相同定义大小写不一致Inconsistent case for same identifier
procedure DoSaveEvent(ATotal, ACur: Integer);
begin
if Assigned(FSaveEvent) then
FSaveEvent(aTotal, aCur);
end;
如上面的代码所示,参数位大写,在使用时为小写,这个不符合编码规范,建议关注这方面的提示,使代码更规范。
4. 结束语
在团队合作中统一的代码规范是非常有必要的。提高代码质量、提高代码可读性等起到一定作用,上面只是列举了部分内容,分析报告中的General分支下还有很多好的建议,我们日常工作中都能应用到,另外该工具的帮助文档虽然简单,但各项建议的含义都有说明,大家不妨读一下。
http://www.cnblogs.com/gleam/archive/2013/05/08/3066679.html
Pascal Analyzer 4 代码分析使用简要说明的更多相关文章
- 使用Memory Analyzer tool(MAT)分析内存泄漏(二)
转载自:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html 前言的前言 写blog就是好,在大前提下可以想说什么写什么,不像投稿那 ...
- 使用Memory Analyzer tool(MAT)分析内存泄漏
前言的前言 写blog就是好,在大前提下可以想说什么写什么,不像投稿那么字字斟酌.上周末回了趟成都办事,所以本文来迟了.K117从达州经由达成线往成都方向走的时候,发现铁路边有条河,尽管我现在也不知道 ...
- Android4.0图库Gallery2代码分析(二) 数据管理和数据加载
Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...
- 免费的Lucene 原理与代码分析完整版下载
Lucene是一个基于Java的高效的全文检索库.那么什么是全文检索,为什么需要全文检索?目前人们生活中出现的数据总的来说分为两类:结构化数据和非结构化数据.很容易理解,结构化数据是有固定格式和结构的 ...
- 虚拟机创建流程中neutron代码分析(二)
前言: 当nova服务发送了创建port的restful调用信息之后,在neutron服务中有相应的处理函数来处理调用.根据restful的工作原理,是按照 paste.ini文件中配置好的流程去处理 ...
- 虚拟机创建流程中neutron代码分析(三)
前言: 当neutron-server创建了port信息,将port信息写入数据库中.流程返回到nova服务端,接着nova创建的流程继续走.在计算节点中neutron-agent同样要完成很多的工作 ...
- Hive metastore整体代码分析及详解
从上一篇对Hive metastore表结构的简要分析中,我再根据数据设计的实体对象,再进行整个代码结构的总结.那么我们先打开metadata的目录,其目录结构: 可以看到,整个hivemeta的目录 ...
- 2018-2019-2 20165312《网络攻防技术》Exp4 恶意代码分析
2018-2019-2 20165312<网络攻防技术>Exp4 恶意代码分析 知识点总结 1.有关schtasks schtacks的作用:安排命令和程序定期运行或在指定时间内运行.从计 ...
- 20155208徐子涵 Exp4 恶意代码分析
20155208徐子涵 Exp4 恶意代码分析 实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使 ...
随机推荐
- 创见WiFi SD卡破解之路
我最近搞了张Transcend WiFi SD,颇为得意.它可以让我在几秒钟内将单反(奶昔,相当便携)中拍摄的照片传到任何支持wifi的设备上.我很喜欢在旅途中拍摄和分享图片,所以对我而言,可以无线传 ...
- Python+django开发环境搭建
Python目前主版本有2个,2.7+和3.4+ 新入手,决定还是从2.7开始 先从python官网https://www.python.org/下载python2.7.10,64位版本(这里注意,选 ...
- Android Animations动画使用详解
一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画 ...
- 犯罪团伙利用POS机刷信用卡积分转卖 年获利千万
今年1月20日,广东省公安厅展示去年缴获的盗刷专用POS机. 今年1月20日,广东省公安厅展示了一批缴获的盗刷信用卡工具. 他们是一群靠信用卡谋生的年轻人,平均年龄不超过30岁. 他们将各银行信用 ...
- grunt用来压缩前端脚本
grunt作为一个任务管理工具,提供丰富的插件和强大的自动化管理功能.需要安装node及npm. 主要使用到两个文件,一个是npm的依赖配置文件package.json { "name&qu ...
- 高可用mysql集群搭建
对web系统来说,瓶颈大多在数据库和磁盘IO上面,而不是服务器的计算能力.对于系统伸缩性我们一般有2种解决方案,scale-up(纵向扩展)和scale-out(横向扩展).前者如扩内存,增加单机性能 ...
- [译]Stairway to Integration Services Level 8 - SSIS 工作流管理高级
介绍 在前两个章节我们,建立了一个新的SSIS包,简单的使用了一下scripting还有优先约束,并且测试了MaxConcurrentExecutables 属性. 同时实验了 “On Succe ...
- 把Orchard部署到Windows Azure Web Sites
很久前就想做个人站点,主要用来记录自己的生活,我喜欢摄影,烘焙…然后又刚刚入皮坑,这些都可以放在网站上展示一下,或许还能为自己带来收入. 然后手上刚好有Azure的试用,于是乎动力就上来了. 以下是部 ...
- Setting property 'source' to 'org.eclipse.jst.jee.server [问题点数:40分]
链接地址:http://bbs.csdn.net/topics/390131469 警告: [SetContextPropertiesRule]{Context} Setting property ' ...
- 【转载】CentsOS系统inotify实时监控服务器文件(夹)定制事件处理程序
原始博文和参考博文 1.CentsOS系统inotify实时监控服务器文件 2.Linux中让进程在后台运行的方法 3.linux inotify 监控文件系统事件 非常好 方法一 说明: 服务器系统 ...