なんだこれは

はてなダイアリーから移転しました。

scan-buildとsplintによるダメだし

某だめだめなコードをもらっていたのを思い出したので、遊んでみることにした。

だめな子

だめな子をsplintとscan-buildでいじってみた。

だめな子

#include <stdio.h>
int main(void); 

int main(void) {
	char a;
	a = 'K';
	printf("%s\n",a);
}

splint君の登場です。

splintくん、やっておしまい!

splint owata.c

さあ、あっというまですよ。

Splint 3.1.2 --- 17 Nov 2010

owata.c: (in function main)
owata.c:7:16: Format argument 1 to printf (%s) expects char * gets char: a
Type of parameter is not consistent with corresponding code in format string.
(Use -formattype to inhibit warning)
owata.c:7:11: Corresponding format code
owata.c:8:2: Path with no return in function declared to return int
There is a path through a function declared to return a value on which there
is no return statement. This means the execution may fall through without
returning a meaningful result to the caller. (Use -noret to inhibit warning)

Finished checking --- 2 code warnings

はあ、はあ、なるほど。

  • printfは %sだから char *型を期待しているのに、char型だよ
  • main 関数 int型なのに、値がかえらないよ。

scan-build

scan-build gcc owata.c

owata.c: In function ‘main’:
owata.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
owata.c:7:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat]
printf("%s\n",a);
~^ ~
%d
ANALYZE: /usr/include/stdio.h __sputc
ANALYZE: owata.c main
1 warning generated.
scan-build: Removing directory '/var/folders/LN/LNFCJNngETGSREN-brHnnU+++TI/-Tmp-/scan-build-2010-12-11-1' because it contains no reports.

ふむふむ。

  • %sだから char*型を期待しているのに、int型だよ。
  • だから%sじゃなくて、%dじゃないの?

まじか!
って aはchar型だよ?

あれ?一つ足りない。scan-build って splintに負けちゃうの?

gcc optionだ!

そういえば、gcc のオプションってのがあったな!
素のgccの警告を見てみる。

gcc owata.c

owata.c: In function ‘main’:
owata.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

これがWallだ

gcc -Wall owata.c

owata.c: In function ‘main’:
owata.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
owata.c:8: warning: control reaches end of non-void function

では、

scan-build gcc -Wall owata.c

owata.c: In function ‘main’:
owata.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
owata.c:8: warning: control reaches end of non-void function
owata.c:7:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat]
printf("%s\n",a);
~^ ~
%d
ANALYZE: /usr/include/stdio.h __sputc
ANALYZE: owata.c main
1 warning generated.
scan-build: Removing directory '/var/folders/LN/LNFCJNngETGSREN-brHnnU+++TI/-Tmp-/scan-build-2010-12-11-1' because it contains no reports.

よしよし

8行目のvoidでない関数で、最後についちゃったよがちゃんと出た。