静的解析の落とし穴を避ける方法


17

私はジョエル・テストで少なくとも11点を獲得する会社で働いています。少なくとも紙の上では。

ただし、実際には、期待どおりに機能するものはなく、プロジェクトはDEFCON 1で半年間使用されています。今、私の同僚のほとんどは、日曜日の午後6時に帰宅できれば幸いです。

動作していないように感じた一見良いプラクティスの1つは、静的分析ツールの使用です。このプロジェクトは、gcc -Wall警告と独自の非常に高価な「C / C ++」ツールの両方を追跡します。

GCCの警告は、実際の(ほとんどの場合、不快ではない)バグを指すことはほとんどありません。

ただし、プロプライエタリなツールは、暗黙的なキャストや文字列リテラルのsizeof'ingなどをリストします。暗黙のキャストもスタイルブックでブラックリストに載っています。

標準的な慣行では、すべての警告を黙らせる必要があります。これにより、主に誤検知である警告が除外されることに注意してください。これは問題ではありません。

結果は次のとおりです。

  1. 人々はすべての右辺値とすべての引数に型キャストを追加し、プロセスで実際に問題のある型の不一致を隠します。
  2. 人々は1つのバグで紹介するか、別の問題のある言語機能を使用します(sizeofの代わりにstrlen、strcpyの代わりにstrncpyなど)。
  3. 警告は沈黙します。
  4. バグレポートが開始されます。

主なポイントは、元のコードが機能しており、言語能力の範囲内で安全に遊んでいた人々によって書かれていたのに対し、修正はそうではなかったことです。

今、私はこの会社が救われるとは考えていません。ただし、「プロ」ツールを使用するためのより良い、できれば機能する方法があるかどうか、または私が将来決定を下す場合にそれらの使用を完全に避けるべきかどうかを知りたいです。

すべてのプログラマーが失敗することのない天才だとは限らないソリューション。なぜなら、そうであれば、そもそもツールを使用する必要がないからです。


1
サイドノート:«-Wall»以外のGCCには«-Wextra»オプションがあり、さらに両方のメタオプションに何らかの理由で含まれていない警告があります。詳細については、ドキュメント参照してください。一般に、すべてのオプションには、メタオプションによって有効にされているかどうかが記載されています。したがって、有効になっていないものをすべて見つけるには、ドキュメント全体で«-Wall»と«-Wextra»の両方の単語をハイライト表示すると、どちらがまだ使用されていないかがわかります。
こんにちは天使14

また、GCCは«-Wextra»の多くを«-Wall»に含めなかったのではないかと付け加えます。私を信じて、これらのフラグのいくつかは非常に便利です。少なくともこれらの警告により、何時間ものデバッグから解放されます。
ハイ天使14

1
誰も答えにコードレビューについて言及していないことに驚いています。私にとっては、いくつかの安っぽいハッキングにこっそりしようとしている人々は、コードレビューによってブロックされていたであろう...
dyesdyes

回答:


16

ただし、実際には、期待どおりに機能するものはなく、プロジェクトはDEFCON 1で半年間使用されています。今、私の同僚のほとんどは、日曜日の午後6時に帰宅できれば幸いです。

これは確かに問題のかなりの部分です。ソフトウェアエンジニアは、週に40時間以上生産的に作業することはできません。それを超えると、仕事の能力に深刻なダメージを与えます-週80時間働いてもプロジェクトにほとんど価値がなく、時にはチームがより多くのエラーを導入するため、プロジェクトが後退することさえあります修正できます。半年間、週60時間以上を行っている場合は、チーム全体で十分な休憩をとり、週40時間で戻ってくる必要があります。キーボードがあまりにも酷使されているため、キーボードを叩くことができない労働力では何も解決できません。

ただし、プロプライエタリなツールは、暗黙的なキャストや文字列リテラルのsizeof'ingなどをリストします。暗黙のキャストもスタイルブックでブラックリストに載っています。

ツールを完全にドロップするか、再構成/交換する必要があります。すべての暗黙のキャストに関する警告は、だれもが対処するには大きすぎます。


週40時間の制限についての研究への参照を提供してもらえますか?

11
ここここは、初心者向けです。週に40時間以上の生産的な作業を行うことができないことは、非常によく文書化されています。簡単なGoogleで、一連の記事を見つけます。
DeadMG

5
2つの小さな、しかしIMHOの重要な修正:40時間/週の制限はおおよその平均値であり、ルールは長期間にのみ適用されます。チームが重要な締め切りの前に余分な時間を置いて、その後回復することは問題ありません(多分数日休むことさえあります)。また、制限は人によっても時間によっても異なります。問題なく週43時間働く人もいれば、35人しかいない人もいれば、週によっては他の人より生産性が高い人もいます。しかし、数週間以上にわたってかなりの残業を続けていくと、実際に深刻な問題を引き起こします。
ペテルトレック

13

私はジョエル・テストで少なくとも11点を獲得する会社で働いています。少なくとも紙の上では。

このテストは、ソフトウェア会社にわずかに関連しています。私はそれについての誇大広告を理解していません。あなたは12を獲得することができ、それでも100%のがらくたプログラマーがいます。人々はツールよりもはるかに重要です。

ただし、プロプライエタリなツールは、暗黙的なキャストや文字列リテラルのsizeof'ingなどをリストします。暗黙のキャストもスタイルブックでブラックリストに載っています。標準的な慣行では、すべての警告を黙らせる必要があります。これにより、主に誤検知である警告が除外されることに注意してください。これは問題ではありません。

これは、すべての静的アナライザーの最大の問題です。誤検知が多すぎます。これを処理する唯一の方法は、特定の問題に対して警告を出すようにツールが設定された理由を詳細知ることです。その場合にのみ、警告が偽であるかどうかの適切な仮定を行うことができます。

暗黙の型キャストの具体的なキャストの場合、それはので、彼らが正式として知られているC.中2(マロン)暗黙の型変換規則によって引き起こされるいくつかの非常に一般的な、C言語の微妙なと危険なバグの存在である整数プロモーションルール通常の算術変換。すべてのプロのCプログラマーの10人に1人しかこれらの2つのルールが何をするのか、何をしないのかを説明できないと思います。しかし、これらのルールは非常に基本的なものであり、通常のCプログラムの行間に何千回も適用されます。

MISRA-C標準では、これらの危険な暗黙の変換規則を説明するために章全体を費やし、暗黙の変換に起因するバグを回避するための多数のかなり複雑な規則を追加しました。これは、市場のすべての静的アナライザーにかなりの影響を及ぼしました。

Cプログラマなら、そのMISRA-Cの章、または少なくともGoogleで説明した2つのプロモーションルールを読んで、できる限りそれらについて読むことをお勧めします。これらのルールについて知っておくべきことがすべてわかっている場合にのみ、静的アナライザーを無視できます。

今、私はこの会社が救われるとは本当に思っていません。ただし、「プロ」ツールを使用するためのより良い、できれば機能する方法があるかどうか、または将来私が決定を下す場合にそれらを使用することを避けるべきかどうかを知りたいです。

すべてのプログラマーが失敗することのない天才だとは限らないソリューション。なぜなら、そうであれば、そもそもツールを使用する必要がないからです。

簡単な方法はありません。実際の問題は、実際にはツールではなく、あいまいなC言語です。一見簡単な言語のように思えるかもしれませんが、行の間には非論理的で奇妙なメカニズムがたくさんあります。また、言語には未定義/未指定/impl.specific動作の何百ものケースがあります。それらのほとんどは、学び、回避する必要があります。

したがって、これらのあいまいな警告をすべて理解するベテランのCプログラマーになるか、そのような人物が少なくとも1人いるチームにいなければなりません。チームにベテランのいないジュニアプログラマーを多数雇用している企業は、これらのツールを使用したり、完全性の高いソフトウェア開発を行ったりするべきではありません。


私は最初から少しずつテストを行いましたが、プログラマをテストするためのツールではなく、雇用主をテストするためのツールです。「お金が払える最高のツール」として適切な同僚を含めることができると思います。そして、私はあなたの答えをSAツールを捨てて、より良く雇う、そして/または訓練することです。前者のポイントは共通点にあるようです。

@qprまた、雇用主をテストするのではなく、雇用主がソフトウェア開発にお金を費やす意思があるかどうかだけをテストします。採用手順、企業目標、市場知識などのようなものは言及されていません。ほとんどの「ITバブル」企業は、そのテストで12点を獲得するだろうと考えています。経営陣は、開発中の製品や、市場が存在するかどうかさえも知りません。

4

問題を修正する方法を尋ねているのか、そもそもどうすればそれを回避できるのかを尋ねているのかどうかは明らかではありません。私は後者を想定しています。

バグを検出して回避するための主要な手段として、静的分析に頼ってきたようです。たぶん、単体テストやメモリチェッカーなどの動的ツールにもっと集中したほうがよかったかもしれません。

特にこれらの誤検知を抑制できない場合、多くの誤検知を生成するツールに依存することは悪い考えです。疲れた/過労した(または怠け者の)プログラマーに、警告を消すための「修正」を行うことを奨励します。誤検知(コメントなど)を選択的に抑制したり、ルールセットを調整したりできない場合は、より優れたツールが必要です。または、少なくとも、控えめに使用する必要があります。

人々が不注意であったり、過労のためにミスをしたりする問題があるようです。コードレビューにもっと時間/労力を費やすべきだったかもしれません。これは、プログラマは天才ではないというあなたの観察に直接対処します。

最後に、非現実的な締め切り、貧しい人々のリソース、および/または要件の変化に苦しんでいるようです。これは管理上の問題であり、そのレベルで対処する必要があります。または、プロジェクトの失敗やスタッフの生産性と士気への長期的な損害のリスクが著しく高くなります。


3

user29079の優れた答えに加えて、問題に追加されるC言語のもう1つの欠陥を追加したいと思います。Javaに移るまで、私はこの欠陥に気付いていませんでした。

警告の目的は、コードの筆者と将来の読者に、何か怪しいことが起こっているという事実を知らせることです。これは、概念としては完全に問題ありません。警告を有効にすればするほど、発見される魚のようなものが増えます。

何が死んで間違っては、ひとつひとつの小さな魚ブツは、すべてのコストで固定しなければならないという考えで、コードを変更することはこれが、OPが説明している問題の原因です。うまく動作しているコードを変更することで、急いで警告を消そうとする失敗した試みです。

同時に、コンパイルするたびにコードが何百もの警告を吐き出したいとは思わない。なぜなら、すぐに警告は無意味になり、誰も新しい警告に注意を払わなくなるからだ。

したがって、これは矛盾する目標の場合のようです。矛盾。

この一見不可能に思える非常に良い解決策は、ステートメントごとに特定の警告を選択的に抑制することができることです。コードを変更する必要があります。

Javaには、@SuppressWarnings( "" )アノテーションを使用したこれに対する優れたソリューションがあります。たとえば、Javaでいわゆる未チェックの変換を行っている場合、コンパイラは警告を発してこれに注意を促し、調べ、これがあなたが何をしているのかを知っている場合の1つであると判断します。そのため、問題のあるステートメントの前に、その直後のステートメントのみ@SuppressWarnings( "unchecked" )に影響する注釈を付けて、自分の人生を進めます。

そのため、警告は消え、コードは変更されず、抑制注釈が構文強調表示によって緑色になり、不明瞭な変換が行われているという事実を文書化しますが、著者は良いと約束します。(*) 誰もが満足しています。

java @SuppressWarnings()では、個々のパラメーターの前に関数を付けることもできます。これにより、特定のパラメーターでのみ発行される特定の警告を無効にすることができます。

ただし、私が知る限り、Cはステートメントの警告を選択的に抑制する標準メカニズムをサポートしていませんでした#pragma warning (nnn:N)。あなたは両方の抑制するために単一の文に対する警告ディレクティブの2行を必要とすることであるの警告は以下のことを文のために有効にすることを休暇を。したがって、Cプログラマーは、この特定のステートメントに関するこの特定の警告が問題ないことを知っていたとしても、個々のステートメントごとに警告を抑制する習慣を身に付けることはほとんどありません。


(*)これを許可すると、家のすべてのプログラマーは何も考えずに警告を抑制していると誰かが主張するかもしれません。これに対する答えは、プログラマーの仕事を改善するためにできる限りのことを行うことができるということですが、積極的に妨害を決定した場合にはできることは何もありません。


言い換えると、最後の警告をすべて削除するためにソースを変更することは良い習慣の鍵ですが、コンパイル可能なコードを変更することは、正当な理由がないだけの単純なコードを排除するため、重要ではありません。良い区別。
ネイサンタギー

2

あなたの会社はより重大な間違いを犯したと(詳細を知らずに)言いたいのですが、これは単なる症状です:生産されたソフトウェアのドメインを適切に決定できず、チームを適切に管理し、合理的な目標を定義できませんでした。

チームが書いているソフトウェアが人間の生活に依存する重要なものである場合、静的解析ツールは重要で有用です。お金で測定されるバグの「コスト」は(皮肉なことを無視して)高いため、ジョブには特別なツールが必要です。言語機能を安全に使用するためのCとC ++の両方のガイドラインがあります(回避する対象と回避する方法を読んでください)。
ただし、このような状況で従業員を日曜日に働かせることは非常に悪い考えです。さらに、あなたが提供したコンテキストから、私は、ずさんな仕事が頻繁ではないことを推測します。この場合、問題は非常深刻です経営陣は「より良い」ツールを使用してそれを解決しようとしています。残念ながら、それは物事の仕組みではありません。もし私が正しければ、別の仕事を探し始めることを提案するところまで行きます。ミッションクリティカルなソフトウェアの悪さは、訴訟の見通しは言うまでもなく、あなたを悩ませ、職業上の評判を損なう可能性があります。

一方、あなたのチームがそれほど重要でないものを書いている場合、偽陽性率の高い「静的分析」ツールはあなたを遅くするだけであり、あなたが指摘したように、人々は通常、この場合、根本的な理由を修正しようとするのではなく、警告を回避するだけで、有効性の極大値を見つけます。そのため、これらのツールを使用すると、実際にはソースコードの品質が低下する可能性があるため、通常は使用しないでください。

場合あなたは、いくつかのCまたはC ++のコードを書いているソフトウェアチームを管理する必要がある、私は最初のメインプロジェクトの目標が何であるかを判断言うと思います。バグのないコードを書くことが最も重要な場合(たとえば、iOSおよびAndroid用の新しい超素晴らしいソーシャルアプリがこれに適合しない場合)、静的分析を使用します。しかし、これが当てはまる場合は、優れたプログラマーを選択し、適切なワークロードと適切な週40時間の健全な環境で作業させることがはるかに重要です。

奴隷のように扱われれば、人々は責任を持って仕事をすることができません(そして、私の休日を占領している人はまさにこれです)。彼らは)。

最下点:目標を把握し、使用するツールとプロセスを決定します。管理者が(悪い)管理者に強制する可能性があるため、利用可能なツールでプロセスを定義(目標を達成)しないでください。


1

k.steffの答えで述べたように、「C」の静的分析ツールは、危機的な状況でソフトウェアを構築している場合(飛行機ソフトウェア)に便利であり、再現不可能なバグが発生する開発の数か月後ではなく、初日から使用する必要があります)。

開発プロセスの後半でこれらの種類のツールを使用することは、通常、プロセスの初期段階で不適切な設計選択の兆候です。

重要ではないソフトウェアでは、これらの種類のツールは次の
目的に役立ちます。それは彼らに彼らのパワーポイントレポートで達成するのが簡単なアクションを与えます)。
-「有毒」な開発者を忙しくしてください。彼らにツールを設定させ、ツールの結果を分析させてください。そうすれば、彼らの厄介なバグを修正する時間ができます。
-コーディング規則を実施します。その場合、初日から使用する必要があります。ただし、適切なコードレビューツールを選択することをお勧めします。

私の意見では、このような高価で時間のかかるツールを避けるか、「有毒」な人々を忙しくしておくためにそれらを使用する必要があります。


1

私はジョエル・テストで少なくとも11点を獲得する会社で働いています。少なくとも紙の上では。

ジョエルテストによる検証は、優れた実践の尺度ではありません。ただし、ジョエルテストによる無効化は、不良/不足しているプラ​​クティスの尺度です。言い換えれば、それは必要であると見なすことができますが、十分ではありません。

今、私の同僚のほとんどは、日曜日の午後6時に帰宅できれば幸いです。

管理に問題があるようです。体系的な残業は、物事を成し遂げるための解決策ではありません。どちらかといえば、それは物事が働いているよう見え、技術的負債を蓄積するための解決策です。

今、私はこの会社が救われるとは本当に思っていません。ただし、「プロ」ツールを使用するためのより良い、できれば機能する方法があるかどうか、または将来私が決定を下す場合にそれらを使用することを避けるべきかどうかを知りたいです。

はい、健全な方法で静的コード分析を使用する方法があります。

彼らは多くの価値を提供でき、通常は提供します。(コンパイラの警告のように)静的解析ツールは(せいぜい)不具合報告のヒントを提供するだけで、バグレポートではなく、確実性を提供できることを覚えておく必要があります。

意思決定者は、静的分析フラグとアプリケーションの欠陥を混同しているようです。

暗黙のキャストもスタイルブックでブラックリストに載っています。

これは、静的分析の問題ではなく、管理能力の問題のように聞こえます。

結果は次のとおりです。

人々はすべての右辺値とすべての引数に型キャストを追加し、プロセスで実際に問題のある型の不一致を隠します。

人々は1つのバグで紹介するか、別の問題のある言語機能を使用します(sizeofの代わりにstrlen、strcpyの代わりにstrncpyなど)。

警告は沈黙します。

バグレポートが開始されます。

これらはすべて、定期的なレポートの見栄えを良くする方法であり、コードの問題を修正する方法ではありません(管理能力の問題があるようです)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.