// 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)
//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 #include
int main(void) { char *some_mem; int size1=1048576; some_mem=(char *)malloc(size1); printf("Malloed 1M Memory!\n"); free(some_mem); exit(EXIT_SUCCESS); }
//END
使用splint检查malloc1.c
$ splint malloc1.c Splint 3.1.1 --- 28 Apr 2005
malloc1.c: (in function main) malloc1.c:9:25: Function malloc expects arg 1 to be size_t gets int: size1 To allow arbitrary integral types to match any integral type, use +matchanyintegral.
Command Line: Setting +showconstraintlocation redundant with current value over.c: (in function main) over.c:6:3: Likely out-of-bounds store: buf[10] Unable to resolve constraint: requires 9 >= 10 needed to satisfy precondition: requires maxSet(buf @ over.c:6:3) >= 10 A memory write may write to an address beyond the allocated buffer. (Use -likely-boundswrite to inhibit warning)
Command Line: Setting +showconstraintlocation redundant with current value bound.c: (in function updateEnv) bound.c:6:19: Possible out-of-bounds store: strcpy(str, tmp) Unable to resolve constraint: requires maxSet(str @ bound.c:6:26) >= maxRead(getenv("MYENV") @ bound.c:5:9) needed to satisfy precondition: requires maxSet(str @ bound.c:6:26) >= maxRead(tmp @ bound.c:6:30) derived from strcpy precondition: requires maxSet() >= maxRead() A memory write may write to an address beyond the allocated buffer. (Use -boundswrite to inhibit warning) 错误原因: 由于使用strcpy函数时,没有指定复制字符串的长度,所以可能导致缓冲区 溢出.后面的updateEnvSafe函数,使用了strncpy进行字符串复制,避免了这种情况.
testlint.c: (in function foo2) testlint.c:6:7: Variable p declared but not used A variable is declared but never used. Use /*@unused@*/ in front of declaration to suppress message. (Use -varuse to inhibit warning)