您的位置:首页 > 运维架构 > Linux

linux下splint检测C语言代码质量

2017-09-08 15:59 330 查看
在linux下并没有pclint,可以使用splint代替。

splint使用

一.splint介绍

splint是一个静态检查C语言程序安全弱点和编写错误的工具。splint会进行多种常规检查,包括未使 用的变量,类型不一致,使用未定义变量,无法执行的代码,忽略返回值,执行路径未返回,无限循环等错误。同 时通过在源码中添加注记给出的附加信息,使其可以进行功能更加强大的检查。而注记,则是对文件中的函数、变 量、参数以及类型进行假定的一种的程式化的注释。

二.splint的安装

下载地址:

http://www.splint.org/downloads/splint-3.1.2.src.tgz

文件: splint-3.1.2-src.tar.gz

大小: 2272KB

下载: 下载

源码包安装:

tar zxvf splint-3.1.2.src.tgz

cd splint-3.1.2

mkdir /usr/local/splint

./configure –prefix=/usr/local/splint

make install

vi ~/.bashrc

添加:

export LARCH_PATH=/usr/local/splint/share/splint/lib

export LCLIMPORTDIR=/usr/local/splint/share/splint/import

source ~/.bashrc

export PATH=/usr/local/splint/bin/splint:$PATH

三.splint的使用

1.空引用错误

在引用没有指向任何内存地址的指针时,会导致这种错误.也就是使用了一个没有赋值的指针.

splint支持一种特别的注释.这种注释写在C程序代码中,用于对程序进行特殊说明.

如下面这段程序.使用了/@null@/进行了说明,表示说明*s的值可能会是NULL.

//null.c

char firstChar1 (/@null@/ char *s)

{

return *s;

}

char firstChar2 (/@null@/ char *s)

{

if (s ==NULL) return ‘\0’;

return *s;

}

//END

使用splint扫描这个程序时,会输出:

splint null.c

Splint 3.1.1 — 28 Apr 2005

null.c: (in function firstChar1)

null.c:3:11: Dereference of possibly null pointer s: *s

null.c:1:35: Storage s may become null

Finished checking — 1 code warning found

由于firstChar1和firstChar2都使用了null说明,表示指针s可能是个NULL值.

所以,splint会对s值的使用情况进行检查.因为firstChar2函数中,对s的值进行

了NULL的判断.所以,没有对firstChar2函数的指针s输出警告信息.

2.未定义的变量错误

C语言中,要求先定义变量,而后才可使用.所以,当使用一个没有定义的变量时,编译就会出错.

如下例,使用/@in@/说明的变量,表示必须进行定义.使用/@out@/说明的变量,表示在 执行过此函数后,这个变量就进行了定义.

// usedef.c

extern void setVal (/@out@/ int *x);

extern int getVal (/@in@/ int *x);

extern int mysteryVal (int *x);

int dumbfunc (/@out@/ int *x, int i)

{

if (i > 3) return *x;

else if (i > 1)

return getVal (x);

else if (i == 0)

return mysteryVal (x);

else

{

setVal (x);

return *x;

}

}

// END

使用splint检查usedef.c

$ splint usedef.c

Splint 3.1.1 — 28 Apr 2005

usedef.c: (in function dumbfunc)

usedef.c:7:19: Value *x used before definition

An rvalue is used that may not be initialized to a value on some execution

path. (Use -usedef to inhibit warning)

usedef.c:9:18: Passed storage x not completely defined (*x is undefined):

getVal (x)

Storage derivable from a parameter, return value or global is not defined.

Use /@out@/ to denote passed or returned storage which need not be defined.

(Use -compdef to inhibit warning)

usedef.c:11:22: Passed storage x not completely defined (*x is undefined):

mysteryVal (x)

Finished checking — 3 code warnings

//错误原因: 由于程序中没有对x进行定义,所以报未定义错误.但setVal()使用了/@out@/ 说明,所以

在setVal(x);和return x;中,没有报未定义错误.

3.类型错误

C语言中的数据类型较多,各个之间有些细微差别.splint也可以对变量类型进行检查.

示例1:

//bool.c

int f (int i, char *s,bool b1, bool b2)

{

if (i = 3) return b1;

if (!i || s) return i;

if (s) return 7;

if (b1 == b2)

return 3;

return 2;

}

//END

使用splint进行检查:

$ splint bool.c

Splint 3.1.1 — 28 Apr 2005

bool.c: (in function f)

bool.c:4:5: Test expression for if is assignment expression: i = 3

The condition test is an assignment expression. Probably, you mean to use ==

instead of =. If an assignment is intended, add an extra parentheses nesting

(e.g., if ((a = b)) …) to suppress this message. (Use -predassign to

inhibit warning)

// 错误原因: if语句中的条件表达式是一个赋值语句.

bool.c:4:5: Test expression for if not boolean, type int: i = 3

Test expression type is not boolean or int. (Use -predboolint to inhibit

warning)

// 错误原因: if语句中的条件表达式的返回值,不是布尔型,而是整型.

bool.c:4:8: Return value type bool does not match declared type int: b1

Types are incompatible. (Use -type to inhibit warning)

// 错误原因: 返回值是布尔型,而不是整型.

bool.c:5:6: Operand of ! is non-boolean (int): !i

The operand of a boolean operator is not a boolean. Use +ptrnegate to allow !

to be used on pointers. (Use -boolops to inhibit warning)

// 错误原因: “!”操作符的操作数不是布尔型,而是整型i.

bool.c:5:11: Right operand of || is non-boolean (char *): !i || s

// 错误原因: “||”操作符的右操作数不是布尔型,而是字符指针.

bool.c:7:5: Use of == with boolean variables (risks inconsistency because of

multiple true values): b1 == b2

Two bool values are compared directly using a C primitive. This may produce

unexpected results since all non-zero values are considered true, so

different true values may not be equal. The file bool.h (included in

splint/lib) provides bool_equal for safe bool comparisons. (Use -boolcompare

to inhibit warning)

// 错误原因: 使用”==”对两个布尔型进行比较.应该使用”&&”.

Finished checking — 6 code warnings

示例2:

//malloc1.c

include
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言