代码版本更新后,文本比较能看出增加了哪些行,却不一定能说明调用关系和类结构发生了什么变化。Understand可以比较两个版本的分析数据库,查看函数、类及相关引用的变化。不过,源码里新增了名称,差异列表未必就会出现对应条目,还要结合文件范围、分析状态和实体类型核验。
一、Understand如何比较代码版本结构
版本比较需要两份对应不同代码状态的分析数据库。当前工程和历史工程应分别保存,避免切换源码后重新分析,把原本准备保留的基线更新掉。
1、准备当前版本和历史基线
比较前要记清两份数据库对应的代码版本。目录名称只能辅助识别,不能代替提交记录,尤其要留意两个工程是否实际指向同一份工作目录。
①分别打开【当前版本工程】和【历史版本工程】,进入【Project】→【Configure Project】,核对源码路径、文件范围及语言设置。
②在各自对应的源码状态下,点击【Project】→【Analyze All Files】,完成分析并保存数据库。
③记录两份【数据库文件】对应的【提交标识】,保留历史版本的源码副本。
2、设置比较工程并查看实体变化
①打开当前版本,点击【Compare】→【Comparison Projects】,通过【Open Project】选择历史版本数据库。
②检查比较列表中的【Project】和【Status】,确认选中的是预期基线。
③点击【Locate Changed Entities】,查看【Added】、【Removed】和【Changed】条目。
较早版本可通过Compare菜单中的Set Previous Project设置基线。新增、删除的判断具有方向性,当前版本中存在、历史版本中没有的实体才会列为Added。把两份数据库放反,状态也会相应变化。
3、结合关系图判断结构变化
差异列表适合定位对象,关系图则适合检查变化涉及哪些调用方和被调用方。函数内部逻辑与函数之间的联系,应分别查看。
①在差异列表中选择目标【函数】,打开对应的【源代码差异视图】,核对新增内容。
②右键目标实体,在【Graphical Views】中选择适用的【Compare Butterfly】或【Compare Control Flow】。
③对照图中的【Legend】,检查新增、删除及修改的实体和引用,点击相关【图形对象】查看源码差异。
二、Understand版本差异中新增符号未显示如何核验
排查时可以分开看两个问题,当前数据库有没有识别这个对象,以及版本比较是否会将它单独列出。两者不能混在一起判断。
1、确认新增文件已进入分析范围
①打开【Project】→【Configure Project】,在文件树中查找新增符号所在的【源文件】。
②文件未列入时,右键所属目录执行【Rescan Directory】,或使用【Add File】添加文件。
③检查该目录的【Watched】或【Unwatched】属性,以及文件类型、排除规则和子目录设置。
固定文件列表不会自动纳入磁盘上新建的文件。即使目录处于监视状态,文件仍可能被扩展名筛选或排除规则挡住。文件已经出现在编辑器里,也不等于它已被纳入工程分析。
2、更新数据库并核对定义位置
磁盘上的源码保存后,数据库仍可能保留修改前的结果。只重新打开差异窗口,无法替代重新分析。
①保存新增符号所在的【源文件】,点击【Project】→【Analyze Changed Files】。
②修改过宏、包含路径或语言设置时,改用【Project】→【Analyze All Files】。
③在源码中选中新增名称,右键点击【View Information】,核对【Information Browser】中的实体类型和定义位置。
3、检查宏条件和解析配置
①打开【Project】→【Configure Project】→【C++】,检查【Macros】及头文件搜索路径。
②对照构建配置,补充实际使用的【宏定义】和【包含目录】。
③执行【Analyze All Files】,打开【Analysis Log】,检查新增定义附近的解析错误。
例如,新增函数放在条件编译分支内,而当前工程没有相应宏定义,分析结果可能与预期构建不同。缺少头文件也可能使类型识别不完整。不要为了让函数显示出来随意添加宏,应采用准备比较的那个构建配置。
4、核对符号是否属于比较对象
版本差异列表并非所有名称的增删清单。比较针对具有源码主体的实体,变量、对象以及跨文件的命名空间等,不会作为独立的新增、删除或修改实体列出。
①点击【Compare】→【Locate Changed Entities】,清除名称、类型等限制条件,重新查看【Added】条目。
②选择新增名称所在的【函数】、【类】或【文件】,打开源码差异,检查新增声明。
③在当前源码中选中该名称,打开【View Information】,确认数据库是否已经识别它。
三、Understand怎样交叉复核新增结构是否完整
新增对象可以被识别后,还应检查它出现的位置和关系是否正确。一个名称显示出来,并不能说明相关调用都已经解析完整。
1、用文件比较检查遗漏内容
①点击【Compare】→【Compare Files/Folders】,分别选择历史版本和当前版本的【源码文件夹】。
②打开新增或修改的【文件】,核对符号定义及其所在位置。
③返回【Locate Changed Entities】,对照所属【文件】或【函数】的变化记录。
文件比较能补充实体比较的观察范围,但它检查的是文本差异。文件里出现某段代码,不代表该代码已经按预期配置完成解析,两种结果需要配合使用。
2、核对新增函数的调用关系
①选中新增【函数】,打开【View Information】,展开【Calls】及相关调用关系。
②打开该函数适用的【Compare】关系图,核对新增调用与源码中的调用位置。
③对无法对应的【引用】,返回【Analysis Log】及【Configure Project】检查解析配置,再重新分析。
新函数尚未被调用时,没有调用方可以是正常结果。涉及函数指针、宏或框架调用时,也应结合源码判断,不能仅凭关系图缺少连线,就认定代码没有接入。
总结
版本结构比较适合帮助维护人员确定审查范围,但结果始终依赖数据库中的文件和解析配置。保存基线时附上代码版本、分析设置和工具版本,后续就能分清变化来自源码,还是来自分析条件。对于变量、宏及条件编译内容,保留文本差异作为补充也很有必要。希望这些方法能帮助大家核清版本变化,如有相关需求,欢迎联系咨询。