アカウント名:
パスワード:
実際、次世代静的プログラム解析ツールを導入することで開発方法やテストサイクルに変化はあるのだろうか? 新しい解析ツールは既存のものよりそんなに実力が違うのだろうか?
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
人生unstable -- あるハッカー
そこそこ出来る人による使用例を求む (スコア:2, すばらしい洞察)
「ダメダメな人にでも使わせるとダメダメなプログラムがそれなりの出来になるツール」ではなくて、
「それなりの人に使わせることでそれなりなプログラムがなかなか良い出来になるツール」なのでしょう。
「すごい人に使わせてもすごいプログラムが完璧なできになるツール」でもないと思います。むしろこの場合は、ツールの出来によっては「見当はずれな警告しか出ないでストレスの元にしかならないツール」であるかもしれません。
「こーんなヤツにこんなツールを使わせても役には立たないよ!」という話ばかりでなく、
こちらの話も聞きたいのですが。「甲のツールを使っていたらこんな警告が出て、こんなバグを見つけたよー」とかいう話もよろしく。
Re:そこそこ出来る人による使用例を求む (スコア:2, 参考になる)
ごくまれに、なんで警告が出るんだ出るわけないだろってこともあります。
警告の内容は例えば
1.int型に対しビット演算を行うと「整数型に対してビット演算を行っています」ってな感じの警告が出ます。
この場合unsigned int型でビット演算を行えば警告は出ません。
2.もしchar型の範囲が-127~128だった場合
0xffを代入しようとした場合これも警告が出ます。
型の範囲外の値を代入しようとしているためです。
charの範囲は環境により異なるためなんともいえませんが。
3.short型(16ビット)にint型(32ビット)の変数を代入させた場合「暗黙のキャストが行われます」とか出ます。
この場合、short型にキャストするれば警告が消えます。short型の変数に入れて良いかもチェック巣r必要も出てきます。
ただ、int型(32ビット)にshort型(16ビット)の変数を代入した場合は警告は出ません。
(ほかのツールなら警告が出るかもしれませんが)
4.unsigned int型のiに対し
for(i=100;i>=0;i--)
なんて書いた場合も警告が出ますね。「for文の条件は常に真です。」といった内容だったかと。
5. int data;
char tmp = 5;
data = tmp << 16;
これも警告が出ます。警告の文面は忘れましたが
tmpの型の範囲外へシフトを行っており情報が失われる。だったかな?
tmpは最大8(7?)ビットしかシフトできないためです。
この場合
data = ((int)tmp) << 16;
とすればよかったと思います。
6. #define AAA(data,val) val = data
これも警告が出ます。
#define AAA(data,val) (val) = (data)
とする必要があります。
7. #define BBB(data1,data2,val) \
{ \
(data1)=(val); \
(data2)=(val); \
}
この警告は「valは2度以上使用されます」といった内容だったかと。
BBB(a,b,c++);
と書いた場合cが意図していない内容になるかもしれないためだと思います。
もっと深い警告もありますが今手元にデータが無いので内容覚えてません。
かなりうろ覚えなため間違ってるかもしれません。
そもそも「こんなコード書くなよ」といわれればそれまでですが。
Re: (スコア:0)
(組み込み用とかのコンパイラでは事情が違うのかな)
個人的には、スレッド絡みのrace conditionの可能性、みたいな、ローカルに気をつけていてもわからないものを教えて欲しいかな。
Re: (スコア:0)
1.は、符号付き整数にたいしてビット操作をおこなうのは、符号の反転が
発生することがあるから行儀よくない、ということだろうし。
(ビット列としてみるなら符号無し整数を使うべき)
2.も同様。signed charに対して0xffを代入するのは、まちがえて255を
代入しているのか-1の8bit表現を16進数に書き直したものかが明示的で
ないためだと思われます。
3.は、処理系のエンディアンによってint型のbyte列のどこがshort型に
入るかがちがってくるからでしょう。
4.は、for文の条件は符号無しの条件分岐になるので、常に真ですよ。
Re: (スコア:0)
> 3.は、処理系のエンディアンによってint型のbyte列のどこがshort型に
> 入るかがちがってくるからでしょう。
これは違うでしょう。
int i = 123;
short s;
memcpy(&s, &i, sizeof(short));
とかしてるわけじゃないし。
Re: (スコア:0)
すべて、コンパイラのワーニング(ウォーニング)レベルだと思います。
解析ツールというからには、「freeし忘れのパスがあります」とか指摘してくれるものだと思ってましたが違うんでしょうか?
Re:そこそこ出来る人による使用例を求む (スコア:1, 参考になる)
いや、うろ覚えの内容を列挙しただけですので。。。
あ、ここ間違ってたのか。と気づかせてくれたのでそう思い込んでるだけかな。
>「freeし忘れのパスがあります」とか指摘してくれる
残念ながら指摘してくれません。
例えば
char *get_data_area(int size) {
char *tmp;
tmp = (char *)malloc (size);
return(tmp);
}
なんてコードが有った場合は?
静的解析はプログラムの内容を理解してくれません。
そのためmallocしっぱなしでfreeしていない事や
スレッド、資源の排他制御などは考慮しません。
あくまでも構文におかしな点があるかどうかをチェックしているだけですね。
うっかり間違ったものを見つけてくれるツールという風に捕らえればいいかと思います。
1. if(data||DATA_FLAG1){}
ビット演算のつもりがorだった場合警告してくれます。
2. if(a==0||b==d+1|c==func()){}
これは
・2項演算子が複数あるため()をつけるべき
・||、&&に副作用があります
・内容は忘れましたが2つ目と3つ目の条件式が|になってる
と警告したような気がします。
if((a==0)||(b==(d+1))||(c==func())){}
と修正。
3. int func ( DATA* data ) {
int a = 0;
a = data->b;
}
これはNULLの可能性があるポインタを間接参照しているという警告がでますね。
関数の最初にNULLチェックすべきです。
呼び出し元でNULLチェックしていたとしても警告は出たと思います。
あとaの初期値は無意味だとか。スタックの無駄遣い。
配列の範囲外を指定する可能性がある場合も警告が出ますね。
コーディング上範囲内に収まってる「はず」だったのが
実は範囲外を指定するかもしれない事を指摘したり。
境界調整のポインタは危ないとか。
>アセンブラ経験があればそれほど不思議な警告ではないような。
まぁそうですね。
freeし忘れとかのプログラムの内容を理解してくれる解析ツールなんてあるんだろうか。
あったら教えてください。
Re: (スコア:0)
この間のESECでデモやってた。
http://www.techmatrix.co.jp/products/quality/ctest/feature/70/bugdetec... [techmatrix.co.jp]