文档详情

PC-lint_中文手册(精)

无***
实名认证
店铺
DOC
1.56MB
约221页
文档ID:157727691
PC-lint_中文手册(精)_第1页
1/221

1 基本概念 手册描述的软件有两种方式对于PC市场(Windows、MS-DOS、OS/2),产品是二进制可执行文件格式对于其它平台, 是C源代码形式,名字是FlexeLint我们在手册的全部部分使用术语PC-lint/FlexeLint标识所有平台公共的行为PC-lint/FlexeLint 是一个发现一个模块或多个模块的C和C++程序的勘误表的软件包它使用K&R 和ANSI 作为K&R C的标准;它使用ANSI/ISO 委员会文档作为C++的标准; 很多C ’99 标准的特性集成到这个产品中,但是目前没有支持所有的 C’99标准根据用户程序的大小来决定总共的需要的内存大小尤其是,存储的需求依赖于头文件的大小粗略估计,每2000行头文件需要的内存存储量大约是1MbPC-lint包包含三个可执行文件:一个Windows可执行文件、一个DOS-extended 可执行文件和一个OS/2 32位可执行文件Windows 可执行文件运行在一个Windows环境下的32位控制台应用环境下DOS 扩展的可执行程序运行在MS-DOS环境下,使用80386 DOS 扩展技术来访问所有的存在的扩展内存。

OS/2 32位可执行程序只运行在OS/2环境下FlexeLint包主要由C源代码组成,可以被编译到任何系统FlexeLint安装的详细信息可在FlexeLint包中的"FlexeLint Installation Guide"找到2 简介PC-lint/FlexeLint发现C和C++程序中的怪癖、异质、失灵和臭虫这样分析的目的是发现这些程序中的在集成前的潜在的问题,揭示可能包含敏感的、未检测到的错误的不寻常的结构因为它寻找几个模块而不仅仅是一个,它可以发现编译器不能发现的事情它通常比编译关于很多细节更爱挑剔2.1 一个例子考虑下面的C/C++程序(我们故意使这个例子小巧和可理解):1:2: char *report( short m, short n, char *p )3: {4: int result;5: char *temp;6: long nm;7: int i, k, kk;8: char name[11] = "Joe Jakeson";9:10: nm = n * m;11: temp = p == "" ? "null" : p;12: for( i = 0; i < m; i++ )13: { k++; kk = i; }14: if( k == 1 ) result = nm;15: else if( kk > 0 ) result = 1;16: else if( kk < 0 ) result = -1;17: if( m == result ) return temp;18: else return name;19: }对于大多数的编译器来说,它是一个有效的C (或C++) 程序。

但是,PC-Lint将会报告很多精细的错误在第8行分配给name[11] 字符串覆盖null 字符;在第10行的乘法丢失精度,尽管long 比int长;第11行的比较是有缺陷的;第12行的变量kI没有被初始化;第15行的变量kk 没有被令人信服地初始化;第17行的变量result 可能未初始化;第18行,可能返回一个auto的地址;在小程序中大多数程序者可以容易地标识出这些问题,但是如果程序是几万行、几百万行,这种工作对于机器来说更合适,而不是人2.2 对C++的lintC++ 是一个非常特别的语言不仅是计算机作者的Ray Duncan称这种语言:“是创建的最神秘和最奇异的语言之一”虽然如此,如果C++不存在,它将被创造出来尽管C是一个非常强大的系统程序语言,但是它没有象Fortran般复杂的数字,象Basic般复杂的字符串,象Smalltalk的对象或Pascal 般的边界检查对于C++,你也没有这些但是你有更重要的事情... 有能力创建这些,并且可能需要的特殊的问题域的许多其它程序结构有了这些力量,将有一些混乱、不计后果的骗局、悲伤的失望、言过其实的要求、总体的拒绝和极端的精神欢快。

作者相信,及时地,语言和它的能力将能被更好理解,它的陷井和缺陷将更容易被识别我们希望PC-lint/FlexeLint能对这些做出贡献,尤其是后者Lint的最初理由是松散地相关的K&R C 语言检查和通过提供模块内的严格类型检查和几个模块间的交叉检查满足这两个需要的多模块(独立编译的)的大型语言的检查ANSI C,某些扩展,和C++,更多的扩展,提供严格的类型检查指针不能再化装成 int 或其它指向的类型;enum 不能自由地混合int;函数需要原型,通过名称毁坏,原型必须模块间一致甚至宽松的类型printf() 和scanf() 能能被它们安全的类型iostream.h 中的cout 和 cin代替那么lint 要做什么呢?当编译器技术进化到能保证发现lint十年前能够发现的那种错误时,lint工具也在进化粗略的估计,1985年的PC-lint 版本可以发现27 个警告和9和提示信息进化到目前的版本,可以发现229个警告和162个提示信息虽然几个信息不再和C++ 代码相关,但是大多数仍然相关例如,表达式分析,包括寻找不经常使用的联合操作符,赋值问题的顺序,丢失精度,有符号/无符号不匹配,不寻常的常量,可疑的比较,不寻常的缩排,可疑的截断,非故意的名称隐藏,可疑的初始化,不适当的使用指向自动变量和无规则宏的指针。

尽管C++的很多复杂的特性,它仍然能产生多虫的的程序C++的类型检查仍然没有Pascal严格,但是使用PC-lint/FlexeLint的严格的类型检查选项(见章节8. 严格的类型)可以做到任意的严格未初始化变量仍然是C++的一个问题我们最初地对初始化变量简单扫描,被替换为复杂地对数据流的分析,目标是发现未覆盖的路径,导致变量使用前没有初始化见章节9.1 初始化跟踪.用我们介绍的7.00版本,内部语句的数值跟踪,变量值和成员值能被记住和推论出来如果以后,这些值对于特定的上下文是不合适的,例如,它们能导致超出范围的下标或访问一个NULL指针,给出一个适当的信息见章节9.2数值跟踪作为一个启动技术,数值跟踪被用来检查到大量标准库函数的调用附加地,这些检查可以转移到用户函数见章节 10.1 函数模仿(-function)PC-lint/FlexeLint 能检查多个模块甚至将导致程序神秘的行为的模块间的所有函数的原型和声明不匹配全局数据可能被初始化或没有被访问;原型可能被不曾预料到的转换;等等至少,宏、枚举常量、声明等等,可能仍未使用或多于地声明通常这些不一致将被警告到一个更严重的问题一些C++的特性导致它们的一些静态分析可能C没有。

数据成员的值可以被跟踪,最少在成员函数内是这样构造器能被假定原始的数据允许我们报告使用没有初始化的数据成员析构器允许我们报告没有删除的指针最后,C++提供足够复杂的(某些保守的情况下)设备容易的被获得,尤其对于初学者来说断言用户正常使用存在文献[12, 13, 17, 19, 20, 21, 22] ,很多这些该和不该的集成到这个包中简单的测试决定是否这个lint或任何其它lint是有用的,仅仅用于你的程序,并看看发生了什么2.3 语言定义Kernighan & Ritchie (K&R) 描述了C程序语言作为早期的事实标准由Harbison & Steele提供了这个杰出的标准说明和现有实践在19世纪八十年代,ANSI C 委员会(X3J11) 开发了一个C标准,向上支持K&R (它的其中一个原则是“不要打断工作代码”)大多数卖主接受了这个标准ISO接受ANSI C 定义和作者K&R 、H&S在ANSI标准上做的一些令人尊敬的工作最近,标准被更改和修正,名字为C99和C标准的努力齐头并进,Bjarne Stroustrup和其它人“加上封装”加强了C语言,尤其在抽象类型和面向对象的程序方面。

这个加强的版本,名为C++,得到C的在1991年开始的ANSI(X3J16)和ISO (WG21)团体和标准的广泛的支持对于标准的基础文档的努力是ANSI C标准和有注解的C++ 引用手册(ARM). 这些努力导致对于C++国际的标准对于C 模块,PC-lint/FlexeLint支持C的C89定义和支持和C89不冲突的K&R定义它也支持对于特定编译器的通用扩展见章节12.非标准扩展,章节 5.8编译器适应和章节13. 预处理器为在通用扩充的更多的信息我们逐渐地合成C99的大部分标准作为需要的基础对于C++,PC-lint/FlexeLint 完全支持国际标准3 PC-LINT开始FlexeLint 用户:开始和使用FlexeLint 依赖于你的操作系统和编译器请看伴随这个文档的FlexeLint 的安装注意事项3.1 安装这一部分适合于Windows 95、Windows 98、Windows ME、Windows NT和Windows 2000对于其它操作系统见章节3.7 其它操作系统SETUP 是一个传统的setup/installation程序,将确定目标驱动器是否是有足够的空间,并把文件copy到你选择的驱动器。

我们将把这个目录作为安装目录安装后,将会有下列部分:lint-nt.exe――PC-lint可执行文件;config.exe――PC-lint的配置文件;readme.txt――手册的附录;pc-lint.pdf ――轻便数据格式的操作手册;pr.exe ――一个方便的打印工具;msg.txt ――我们消息描述的ASCII翻译;unwise.exe―― 一个卸载程序;install.log―― 一个安装日志;Lnt\――一个子目录,包含...co-....lnt――对特定编译器的编译选项文件;co.lnt ――一个通用的编译器选项文件;sl-....c ――对non-ANSI 编译器的标准库模块;sl.c ――对non-ANSI 编译器的通用的标准库模块;env-....lnt ――对不同环境下(包括Microsoft's Visual Studio 和不同的编辑器)的选项文件;lib-....lnt―― 对特别的库的选项文件;au-....lnt―― 对作者推荐的检查的选项文件;Test\ ――一个包含不同的测试文件的子目录见章节3.3 运行测试程序;安装后,你将得到信息“I want to start the CONFIG.exe file now”。

你应该回答“Yes”,配置你对编译器和库的合适的选项3.2 配置配置程序(config.exe),也就是我们谈到的配置wizard,有两个基本的操作模式:(i) 作为一个wizard帮助你对你的编译器、库和个人的参数选择合适的选项这个模式在初始化安装后使用,也可以在后来当配置变化时使用;(ii) 作为一个程序以后运行,允许你方便的在以前的配置间切换无论怎样, 我们需要区别两个目录 (可能事实上是同一个):安装目录:安装PC-lint的目录;配置目录:存储配置信息的目录;在一个如果你的安装目录是可写的,安装目录和配置目录可以相同;如果PC-lint被安装在一个只读的文件服务器,配置目录和安装目录必须是不同的PC-lint 没有一个可视的前端它可以运行在命令行、在一个集成开发环境中或在一个智能编辑器中(见章节3.5集成在你的环境)wizard 将创建一个文件lin.bat,你可以lint C和C++文件使用命令:lin options file1 file2 ...lin.bat 将包含一个命令类似这样的形式:InstDir\lint-nt -iConfDir std.lnt &1 &2 ...这里InstDir是安装目录,ConfDir是配置目录,std.lnt 将包含合适的选项来lint。

i 选项(完整的描述见章节5.7 其它选项) 如此命名是因为它能确定include目录和管理寻找文件的寻找不仅仅是寻找头文件特别的,std.lnt,被放置在你的配置目录但是注意,std.lnt也可以放置在你的当前目录,而且有优先级,这也有它的作用std.lnt将混合一个编译器选项文件、一个或多个库选项文件、大小选项和一个options.lnt(影响你长期的错误抑制策略的文件)见章节14.2建议的安装总结一下,wizard 将创建下列文件:LIN.BAT――一个批处理文件,可以被copy到你的PATH 目录下,里面包含一个参考文件STD.LNT;STD.LNT――一个间接lint文件,内容包括一个编译器选项文件、一个选项文件和随意的其它选项和文件;STD_...LNT ――一系列不同版本的STD.LNT ,wizard能够以后从中选择;Options.lnt ――一个方便的中心本地选项文件,你的大部分的lint选项都写在里面;.LSET.BAT ――一个批处理文件,可被用于放置你的PC-lint 可执行文件到你的PATH目录中;使用这些文件可以参考章节3.4Lint你的程序和章节14.2建议的安装Setup。

Wizard将copy一些文件从安装目录(或它的子目录)到配置目录以下是这些文件:co-....lnt ――编译器选项文件;env-....lnt ――环境选项文件;lib-....lnt ――库选项文件;lib-....h ――lib-....lnt 参考的头文件;au-....lnt ――作者建议检查的选项文件;file?.cpp ――在下一章节描述的一对测试程序;3.3 运行测试程序对PC-lint,在你完成安装和配置后,在以前的事件中,PC-lint可执行文件是lint-nt.exe ,在以后的事件中,它可能是lint.exe 或 lint-os2.exeI在我们的例子中,我们将使用lin.bat, 巧妙地配置,包含合适的可执行文件对FlexeLint,你将创建一个类似的Shell脚本(或类似的命令行脚本),为了表达方便的目的,我们假定名字是lin在这个章节,要描述产品的基本操作,我们假定以下定义两个小文件filea.cpp 和fileb.cpp ,这些可以在目录dos-ins\test 中找到从你的配置目录lin filea fileb例子文件filea.cpp 和 fileb.cpp s显示如下:filea.cpp://lint -w2 reduce the warning level to 2class X{static int a;};fileb.cpp:class X{int a;};你将在你的屏幕上见到下列信息:PC-lint for C/C++ (NT) Vers. 8.00, Copyright ...--- Module: filea.cpp--- Module: fileb.cpp_};fileb.cpp 4 Warning 631: tag X defined differently atline 3, file filea.cpp--- Global Wrap-upWarning 1527: static member X::a (line 5, file filea.cpp)not defined并不是你见到的所有信息都是错误信息。

第一行标识出PC-lint的版本;第二行和第三行是过程进行的信息,正常显示被处理的模块名称信息你可以关闭这些'verbosity' 信息或增加它们的详细程度,使用-v... 选项;第四行开始显示错误信息3.4 Lint你的程序要lint你自己的程序,输入一个目录包含你的C和C++模块,我们假定lin.bat(或在主机的操作系统的相似的shell脚本)可以在任何目录运行(例如,已经被放置在你的PATH目录中)这样做的好处是可以简单的表达和简单的打印假定你的程序由下列模块组成:alpha.cppbeta.cgamma.c我们可以lint整个程序使用以下方式:lin alpha.cpp beta.c gamma.c注意:扩展名 .cpp (就象 .cxx) 表明是一个C++模块,扩展名 .lnt 表明一个间接文件(命令行扩展) ,其它的扩展名表明是C模块通常最好首先做一个单独的模块的单元检查 (使用-u 选项) 例如:lin -u alpha.cpp对模块alpha.cpp.做一个单元检查(你的文件的任何子集隶属于单元检查)当做一个单元检查,特定的信息被禁止显示 (例如 "function not used").3.4.1 对C++模块的扩展不考虑扩展的默认处理,你可以使用+fcp flag。

这指出下一个模块将是一个C++模块这将一直起作用,指定用-fcp关闭lin +fcp a1.c a2.c a3.c -fcp a4.c a5.cpp将对待a1.c、a2.c和a3.c 作为C++模块,a4.c 作为C模块,a5.cpp作为一个C++模块选项 +cpp(扩展名) 将被用于加到C++扩展名的列表因此lin +cpp(cc) a1.cc a2.cc a3.c a4.cpp将处理a1.cc, a2.cc和a4.cpp作为C++模块,a3.c 作为C模块选项严格按照顺序的3.4.2 控制消息对于以前没有lint的代码,你将得到大量的信息默认的告警级别是3,意味着你将见到所有的错误告警和情报信息要抑制情报信息,降低告警级别到2,使用-w2 :lin -u -w2 alpha(假定扩展名是.cpp )你也可以使用信息号来抑制信息例如,要抑制告警547号信息,你可以使用选项-e547 :lin -u -e547 gamma.c无论如何,不要气馁有大量的错误抑制选项 (见章节5.2错误抑制选项). 建议建立一个错误抑制制度,见章节14.灵活使用LINT.3.4.3 选项万一你没有注意到,有大量的选项,可以参考章节5. 选项。

要得到选项的总结lin ?3.4.4 命令行的扩展对于多于一个模块的project,你发现把所有模块的名字放到一个lint间接的文件是非常方便的假定这个project的名字是alphabet,创建一个alphabet.lnt文件包含:alphabet.lnt:alpha.cppbeta.cgamma.c它们使用:lin alphabet要lint整个project,你可以把选项放到alphabet.lnt 里面,但这是不被推荐的,因为如果你做一个单元模块检查,你将没有得到这些选项的好处最好,放置与project无关的选项到一个中心文件options.lnt;与Project有关的选项可以放置到你的project目录下的std.lnt 文件更进一步的描述在章节14.2被推荐的的安装3.5 集成到你的环境PC-lint被灵活地设计,以便于你方便地集成到你喜欢的集成开发环境(IDE)或智能编辑器好处是你可以用最小的键击启动PC-lint来处理你当前的文件或当前的project完成后,而且,你能,在多数情况下,快速地和自动地从错误到错误(实际消息到消息)切换,希望用一个单击你子集的编辑器,适当地指出文件中需要注意的位置。

我们,当然,能够提供我们自己的环境,但是我们觉得你应该可能更好的继续使用你自己喜爱的编辑器的现有环境特别的,我们的消息格式是非常灵活的(见章节5.6消息陈述选项)消息重向不仅是通过命令行的标准重定向符(>),而且是被嵌入的作为选项(见 -os(file) 在章节 5.7其它选项). 标语行可以被控制(见 –b在章节5.7其它选项) 和它能被安排成至少一条消息总是产生(用选项+e900) ,对某些环境是必须的另外,间接文件(.lnt 文件)能包含间接文件文件扩展名,可以不是.lnt (见+ext在章节5.7 其它选项).间接文件能包含嵌入的环境变量名(章节 4.1间接(.lnt) 文件.)我们加入一些格式为env-....lnt 的文件,帮助处理集成到特定的IDE'包括:env-BC5.lnt―― Borland's 5.0 IDE;env-bwin.lnt――Borland's 4.0 IDE Windows环境下;env-cw.lnt ――Premia Codewright;env-pwb.lnt――Microsoft's Programmer's Work Bench;env-si.lnt―― Source Insight Editor;env-sled.lnt―― Visual Slick Edit;env-tide.lnt―― Turbo/Borland IDE under DOS;env-vc.lnt―― Microsoft's Visual C/C++, Version 1;env-vc2.lnt―― Microsoft's Visual C/C++, Version 2;env-vc4.lnt―― Microsoft's Visual C/C++, Version 4;env-vc5.lnt―― Microsoft's Visual C/C++, Version 5;这些文件需要时更新。

见我们的web site (在Version 8.00补丁里)3.6 * .dsp处理如果你使用Microsoft Visual Studio,每个project的概要包含在一个扩展名为 .dsp.的文件里这个文件是 ASCII形式,可以用你的编辑器察看这个文件包含模块名称,定义的预处理变量,包含的路径PC-lint/FlexeLint能处理这个文件,展开这些相关到lint的信息,转换这些信息到lint指示,并输出结果到标准的输出结果文件,如果有一个 .lnt 扩展名,能被用于输入到PC-lint/FlexeLint例如, 下列从一个.dsp文件产生一个lint project文件:lint-nt project.dsp >project.lnt这个 .dsp 文件,包括内容 SOURCE= lines. 这些行包括不仅模块名称(C和C++文件),而且包括头文件、资源文件、文本文件等等PC-lint/FlexeLin,当然,仅仅需要模块名称默认的,我们选择任何扩展名是“.c”,和有C++扩展名的文件默认的,C++扩展名是“.cpp” 和“.cxx”, 这个扩展名列表可以被-cpp选项控制。

要想看看转换是怎么进行的,你可以使用verbosity选项来触发一个对每行的信息,例如:lint-nt -v1 project.dsp >project.lnt将提供一个一行一行地转换用 .dsp 文件,可以支持条件语句,例如:!IF "$(CFG)" == "project - Win32 Release"这允许你选择debug或release变量变量CFG 通常确定.dsp 文件内最近的配置你可以改变流提供一个“命令行”选项:+d"CFG=project - Win32 Release"这象一个预处理器定义,除了+d (相对于-d) 阻止后来的重新定义.使用引用是必要的,因为定义包含空格既然有很多种方式解释命令行参数(批处理命令、make file,、命令行),而且处理引用和空格的方式是轻微的区别,最好把这些选项放置到一个单独的.lnt文件,例如:release.lnt:+d"CFG=project - Win32 Release"然后选择一个命令行,例如:lint-nt release.lnt project.dsp > project.lnt如上所示,输出文件(这些例子中的project.lnt)将包含有用的模块列表的选项。

对单元检查,你需要选项列表,而不是模块列表为此,使用--u 选项 (不是 -u). 例如:lin --u project.lnt alpha.cpp这将使用所有没有模块的project.lnt内的选项来进行单元检查,仅仅处理alpha.cpp.3.7 其它操作系统我们提供一个安装程序为OS/2或DOS系统能支持DOS扩展技术如果操作系统不是Windows 9X、Windows 2000、Windows ME和Windows NT,你将使用FlexeLint要安装和开始,见FlexeLint安装注意事项要使用安装程序,放置你的安装盘到CD-ROM驱动器,输入:Drive-letter:\DOS-ins\install按照屏幕上的提示,安装程序不仅安装盘复制文件,而且修改你的环境变量和AUTOEXEC.BAT或CONFIG.SYS最好创建批处理文件做这些事情,以这种方式,当你复制文件时你可以看到什么将会发生的建议,如果发生什么问题,你将有一个记录而且,许多程序员有一套AUTOEXEC.BAT,需要知道怎么修改每一个,不能对目前的一个盲目的修改创建的批处理文件是LCOPY.BAT,批处理文件从安装盘复制LSET.BAT (对OS/2是LSET.CMD)文件到lint目录。

批处理文件设置环境变量(仅仅需要时创建)注意:在DOS下,LCOPY 调用LSET upon termination (如果需要)安装程序同样创建下列文件:LIN.BAT ――(对OS/2是lin.cmd ),一个批处理文件,安装程序将复制到你的PATH目录,并包含一个对STD.LNT的参考STD.LNT――一个间接文件,将指向一个编译器选项文件和一个选项文件STD_...LNT――多个版本的STD.LNT (见章节3.7.1多重配置)options.lnt――A一个方便的中心放置选项文件,你将趋向于使用你的大多数的lint对于这些文件的描述在章节3.4 Lint你的程序和章节14.2 建议的安装3.7.1 多重配置对OS/2和DOS的安装程序为了一个双重的目的首先,它提供了从安装盘到硬盘复制文件的目的,(SETUP做的对于不同的Windows平台)其次,它能创建一个或多个配置(收录在STD.LNT文件)对多重配置的设置(例如,多重编译器,和/或多重内存模式,和/或多重库)是建立多个候选的STD.LNT和提供一个简单的方式切换它们见章节14.2建议的设置t来看STD.LNT的中心作用如果,在你的安装过程中,你回答“Yes”回答问题:“Are you going to set up multiple compilers ...”,然后是关于编译器、内存模式和库重复的很多次的问题。

这些的答案将放置到这些文件中:STD_A.LNTSTD_B.LNTSTD_C.LNT...等等要切换不同的配置,我们提供一个批处理文件CONFIG.BAT可以在你的工作目录使用完整路径名运行 (不需要参数), 可能看起来象:C:\LINT\CONFIG它提供一个配置选项的菜单通过选择合适的字符来选择一个,这个字符决定是哪个文件STD_x.LNT 将替代STD.LNT你,也可以不用使用这种方式CONFIG例如,在一个特定目录,你总是选择'C' 配置(例如STD_C.LNT), 你可以在哪个目录创建一个STD.LNT,包含对下列文件的引用:STD_C.LNT做为选择,你可以简单地复制STD_C.LNT的内容到STD.LNT I在给出的目录.3.7.2 DOS-ins 文件3.7.3 DOS混合注意事项4 命令行PC-lint/FlexeLint的命令行有下列形式:lint option file1 [ file2 file3 ... ]这里命令行名称lint 将根据依赖于操作系统和安装的选择而不同;选项 (描述在章节5.选项) 通常处理这里显式的文件它们也可以点缀在文件中获得特殊的效果如果没有参数给PC-lint/FlexeLint或一个? 作为一个单独的参数,那么提供一个简单的帮助作为输出。

通配符对PC-lint和Unix下的FlexeLint 也是适用的见章节4.1 间接(.lnt)文件.一个模块被认为是一个C++模块,如果它的扩展名是 .cpp 或.cxx 或 +fcp flag 被打开你也可以加新的扩展名到C++名称扩展列表,使用+cpp选项(见章节5.7 其它选项.)4.1 间接(.lnt)文件间接文件可以包含注释;间接文件可以包含环境变量;例如%SOURCE%\a.c // first file%SOURCE%\b.c // second file如果一个间接文件在当前的目录没有发现,将在惯例的地方寻找,例如:lin.bat 可能包含C:\lintpp\lint -iC:\lintpp std.lnt %1 %2 %3 %4std.lnt 将在目录C:\lintpp中查找(如果当前目录中没有std.lnt).4.2 退出代码5 选项5.1 指定选项的规则5.1.1 注释内的选项LINT选项可以放在注释中,例如:/*lint option1 option2 ... optional commentary */ 选项可以有多行//lint option1 option2 ... optional commentary 选项仅为一行选项间要以空格分开,lint命令一定要小写,并且紧跟在/*或//后面,不能有空格。

如果选项由类似于操作符和操作数的部分组成,例如-esym(534, printf, scanf, operator new),其中最后一个选项是operator new,那么在operator和new中间只能有一个空格5.1.2 宏内的选项选项还可以放在宏定义中,当宏被展开时选项才生效例如:#define DIVZERO(x) /*lint -save -e54 */ ((x) /0) /*lint -restore */ 允许除数为0而不告警5.1.3 选项内的空格你可以使用双引号(”),而不是单引号,来保护一个空格,例如:-"dWORD=unsigned short"就象#define WORD unsigned short-dMESSAGE="use unsigned short"就象#define MESSAGE "use unsigned short"5.1.4 选项显示因为选项可能被放于模糊的地方而遗忘,冗余信息选项-vo(见章节5.4冗余信息选项.) 能被用来显示遇到的所有选项5.1.5 选项和其中的字符一些我们更复杂的选项有下列形式-identifier( arg1, arg2, ... )这些选项可以放置在 .lnt 间接文件中和 /*lint 注释中,但是不能放置到命令行中。

对MS-DOS, 可以使用'!' 代替逗号(','). 因此c:\lint\lint -esym(714,alpha) ...可以替换为lin -esym(714!alpha) ...完整的设置是:O.S. Meta Character AlternativeMS-DOS , !Unix () ? [ ] .Macintosh MPW + " & 'LINT的选项很多共有300多种,大体可分为以下几类:5.2 错误信息禁止选项说明:“-” : 表示禁止输出相应的错误消息“+” : 表示允许输出相应的错误消息“#” : 允许使用通配符“?”和“*”除了900级别(900-999)和1900(1900-1999)级别的告警消息缺省是关闭的外,其它的告警消息缺省均是打开的5.2.1 -e# :禁止输出告警号为#的消息;例如 -e504 w关闭错误信息504;-e7??关闭所有700水平的错误;关闭情报信息,最好使用-w2;-e1*s将关闭所有以数字1开头的信息,包括信息12、1413 和1 自己;5.2.2 -e(#) :对于下一个表达式禁止输出告警号为#的消息5.2.3 !e# :在本行禁止输出告警号为#的消息5.2.4 --e(#) :对当前的整个表达式禁止输出告警号为#的消息整个表达式可以是一个if语句、一个while 语句、任何一个for 语句、一个switch语句或者一个表达式语句5.2.5 -e{ # [, #] …} :w禁止输出下一个语句或声明(第一个)告警号为#的消息一般使用在一个lint 的注释中,例如://lint -e{715} suppress "k not referenced"void f( int n, unsigned u, int k ){//lint -e{732} suppress "loss of sign"u = n; // 732 not issued//lint -e{713} suppress "loss of precision"if( n ){n = u; // 713 not issued}} // 715 not issued–elib{715} 被用于在整个函数中抑制信息715 ,而不是在下一个函数中。

–e{732} 将被用于在下一个分配语句中抑制信息732–e{713}将被用于在下一个整个if语句中抑制信息713注意:这个结构可以在一个类的定义前或namespace声明来抑制和类或namespace体相关的信息使用–e{#} 和-save –e# … -restore 是一样的作用通配符可以使用在–e{}中因此–e{7??} 或 –e{*} 都是合法的5.2.6 --e{ # [, #] … } :将禁止它放置的整个区域的信息号#区域可能是一个混合语句、一个函数体、一个类、一个结构、一个联合定义、一个链接规格体如果选项没有放置在任何这些区域,抑制将作用于全体(从出现的地点到模块的结束)它没有扩展模块的结束到下一个模块它将影响对模块的综合报导的信息,但是不影响对全局的综合报导的信息考虑下列例子://lint --e{528} suppress "f() not referenced"static void f( int n, unsigned u, int k ){//lint --e{715} suppress "k not referenced"//lint --e{732} suppress "loss of sign"u = n; // 732 not issuedif( n ){//lint --e{713} suppress "loss of precision"n = u; // 713 not issuedu = n; // 732 not issued}} // 715 not issued--e{528} 抑制告警528 ,发布于模块的综合报导,没有影响其它模块。

e{715, 732} 抑制715和732,发布在函数内,没有影响其它函数e{713} 抑制在符号语句中的丢失精度的信息许多关于-e{}的评论也适用于--e{}象-e{}, 任何--e{}选项被嵌入到语句树中;它可以出现在你的宏中,它可以使用通配符5.2.7 !e# O抑制一行信息(这里#是一个信息号) ,被使用在/*lint(或//lint) 注释它只是抑制给出的一行代码例如:if( x = f(34) ) //lint !e720y = y / x;将抑制信息720 ,对一行可以代替两个单独的lint注释://lint -save -e720if( x = f(34) ) //lint -restorey = y / x;对于C代码,/*lint 格式的注释将更合适:if( x = f(34) ) /*lint !e720 */y = y / x;多个错误信息抑制选项可被允许如下使用,但是没有通配符:n = u / -1; //lint !e573 !e721一个限制条件是:一行消息抑制不能放置在宏内这样是为了速度一个快速地扫描是对每个非预处理输入行寻找字符'!'如果这个选项嵌入在宏内,这样快速的寻找将没办法做到。

5.2.8 -ealetter 抑制参数不匹配信息注意:这只是影响非原型的调用,因此对C++程序没有影响lette可能是:I―― sub-integern ――nominalu ――unsigned vs. signeds ――same size这些选项对选择的不同类型抑制信息516 (参数类型不匹配) 告警信息 516 被发布当实参和/形参在函数调用和原型中不一致5.2.8.1 -eai : 整型数子类参数不一致,如:char/short vs. int参考 +fxc 和 +fxs.5.2.8.2 -ean : 名义上的参数不一致,如:字节数相同(都是32位)的int和long,unsigned int 和unsigned long等,也支持short 和 int,当它们字节数相同时5.2.8.3 -eas : 参数大小相同,如:如果int和pointer字节数相同,那么如果f()的参数应该是pointer的话,用f(3)整型数调用就会报错,设置此项可以关闭告警5.2.8.4 -eau : 参数类型一致,但是符号类型不一致,如:unsigned int和int,例如,如果函数f期望一个unsigned int,n是一个int,那么调用f(n)将发出告警信息516,这个信息可以通过设置-eau 而不显示。

以上四个选项主要用于非原型的旧风格的C语言程序其中-ean和-eau 正交,eas涵盖了ean和eau举例来说,如果-eas 被设置,没有必要设置-eau.5.2.9 -efile( #, file [, file] ... ) 对指定文件禁止输出告警号为#的消息这个象-esym ,但是只是用于那些参数是文件名的错误信息例如 7, 305, 306, 307, 314, 404, 405, 406, 537, 766)请注意,这个选项不是抑制一个文件内的信息,而是关于这个文件的信息5.2.10 -efunc( #, Symbol [, Symbol] ... ) 对于函数Func,禁止输出告警号为#的消息例如:int f( int n ){return n / 0; // Error 54}将报告信息54 (被0除)要抑制这个信息,你可以使用选项-efunc( 54, f )这个将抑制任何的发生在同样函数的被0除的信息efunc 选项和-esym(抑制某个函数名的信息,或任何错误信息中的参数的符号名的信息) 选项相比,这两个都支持通配符成员函数必须表示为使用范围操作符,因此-efunc( 54, X::operator= )5.2.11 -elib( # [, #] ... ) 对于库头文件禁止输出告警号为#的消息# m可以是通配符,一个更方便的方式是对库头文件设置一个检查级别,使用-wlib(level). 5.2.12 -elibsym( # [, # ] ... ) 对于所有库头文件中的符号禁止输出告警号为#的消息,此告警不同于elib之处在于-elib(#)仅仅当分析头文件时不输出相应的告警,如果你在源程序中使用了会导致告警#的变量等,在分析源程序时还是会告警的,因此要想完全的关闭该告警,使其在头文件和源文件中均不出现,请使用本选项。

例如, 假定一个库定义了一对类:class X { };class Y : public X { ~Y(); };这将导致信息1510, 基类X h没有析构器 注意,信息将被延期直到见到子类Y 的一个析构器选项-elib(1510) 当处理库头文件时将抑制这个信息如果在用户自己的代码中,有一个声明:class Z : public X { ~Z(); };诊断将发布信息,尽管使用-elib(1510) I,因为这个声明在库代码之外用户可以抑制信息使用-esym( 1510, X )但是如果有大量的这样的基类都没有析构器,用户可以使用选项:-elibsym( 1510 )5.2.13 -emacro( #, symbol, ... ) 对于宏Symbol,当其展开时禁止输出告警号为#的消息使用这个选项的原因是经常因为对于编译器或第三方的库宏,需要抑制错误信息 5.2.14 -emacro( (#), symbol, ... ) 对于宏Symbol,当其展开时禁止输出告警号为#的消息,与上一个选项的区别是它会先将宏加上一对括号再判断,如:#define DIVIDE( n , m ) n / m那么它会在宏展开时将n / m看作( n / m )来处理。

例如, 假定宏ZERO被定义为:#define ZERO (*(int *)0)当ZERO 被实际使用后,结果是告警信息413 (使用NULL指针)要抑制这个信息,你可能想到使用:-emacro(413,ZERO)这将不总是起作用,归因于事实:信息413被在一个表达式步中给出,而不是语法分析阶段修改的办法是使用:-emacro( (413), ZERO )这将抑制信息413 ,使用语法分析,在宏相关的树节点放置告警信息413抑制需求选项-e(413) 被放置于一个表达式前的/*lint 注释内就好像我们定义ZERO 为:#define ZERO /*lint -e(413) */ (*(int *) 0)5.2.15 -epletter(s) 指针的类型不匹配这个选项指指针到指针的不匹配(错误64),交叉分配、在初始化中隐含分配、函数中返回、 在原型中传递分配等letter 是以下中的一种:n――nominalu――unsigned vs. signednc――nominal charuc――unsigned vs. signed chars――same sizep――all indirect values5.2.15.1 -epn名义上的指针不一致,如:对于指向字节数大小相同的变量的指针 例如 指向short的指针对指向int的指针,这里int和short大小相同。

5.2.15.2 -epu 指针指向的类型仅仅符号不一致例如char 和 unsigned char5.2.15.3 -epnc 指针指向的字符串类型,仅仅名义上不同指针指向的类型不同,一个是char,另一个是signed char ,这里char是默认的signed,或一个是char,另一个是signed char ,这里char是默认的unsigned. 5.2.15.4 -epuc 指针指向的字符串类型,其符号不一致指针指示的类型不同,一个是signed char ,另一个是unsigned char.5.2.15.5 -eps指针指向的类型不同,但大小字节数相同5.2.15.6 -epp指针指向的类型不确定-epn和-epu正交;-eps 包含这两个;-epp 包含其它的;-epnc是-epn的一个特例;-epuc是-epu的一个特例;5.2.16 -esym( #, Symbol [, Symbol] ... ) 于指定的符号Symbol(可以是变量名、函数名等),禁止输出告警号为#的消息,符号Symbol中可以使用通配符*和?例如:-esym( 715, un_* )对任何前三个字符是"un_"的符号抑制信息715 -esym( 512, ?, *::* )对任何名称包含"::"(例如成员变量名称)的符号抑制信息5125.2.17 -etd( TypeDiff [, ...] ) 对于TypeDiff类型,忽略不同地方对其的类型定义不同,用于旧风格C例如, -etd(ellipsis)将抑制两个函数类型不同,一个以省略号确定,而另一个不是的信息。

5.2.18 -etemplate( # [,#] ... ) 抑制当展开模块时的错误信息5.2.19 -wLevel设置告警级别(0,1,2,3,4),0表示不打印任何告警消息,用于先关闭所有告警,然后打开部分告警5.2.20 -wlib(Level) 对库(文件)设置告警级别5.3 变量类型大小选项说明:不同的目标机、编译系统变量类型的的大小(如短整型变量、整型变量等)会有所不同,该类选项用于为目标机设置变量类型的大小例如,如果你要对一个嵌入式系统lint,int 和指针通常是16个字节,你应该确定:lint -si2 -sp2 ...当前的这些大小参数的值,可以使用下列的命令获得:lin -sp6 ?5.3.1 -sb#:设置一个字节的比特数,缺省值为85.3.2 -sbo#: sizeof(bool) ,缺省值是15.3.3 -sc# : sizeof(char),缺省值为15.3.4 -slc# : sizeof(long char),缺省值为25.3.5 -ss# : sizeof(short),缺省值为25.3.6 -si# : sizeof(int),缺省值为45.3.7 -sl# : sizeof(long),缺省值为45.3.8 -sll# : sizeof(long long),缺省值为85.3.9 -sf# : sizeof(float),缺省值为45.3.10 -sd# : sizeof(double),缺省值为85.3.11 -sld# : sizeof(long double),缺省值为165.3.12 -sp# : sizeof(all pointers),缺省值为4和65.3.13 -spN# : size of near ptrs,缺省值为45。

下载提示
相关文档
正为您匹配相似的精品文档