組込みシステムのすべてはコード品質で決まる
組込みシステムのコード品質に関わる私たちの一連の記事で、コード品質とは実に広い話題で、さまざまな角度から議論されうる(されるべき)ことをご紹介しました。最後となる本稿では、もっとも重要な話題についてまとめていきたいと思います。
組込みシステムのコード品質とは何か、なぜそれほど騒ぐのか?
もしロバート・M・パーシグの“禅とオートバイ修理技術“を読んだことがあるなら、品質を定義することに費やす努力が、人生に劇的な影響をするかもしれないことをご存じでしょう。
すべての状況に適用可能なコード品質の定義はありません。しかし、何が優れたコード品質を構成するかについて、以下のとおり、いくつかメトリクスや提案があります。
- 不良の数。これは表面的には明らかですが、実際はどうなのか、どう測定するのでしょうか?もちろん統計的な方法があります。例えば、不良の数を時系列でカウントする。しかし、かなり主観的で、実情や不良の原因について何ら語っていません。
- コードの保守性が高いこと。これは可読性が良く、妥当な工数で理解できることを示唆します。この場合も主観的で、複数の開発者が同じ定義をする可能性は限りなくゼロに近いです。
- コード全体または一部が他のプロジェクトで再利用可能であること。繰り返しになりますが、この指標も、計測が難しく、客観的に再利用性を説明する手段がありません。
- コードが安全でセキュアであること。きっと定義が難しいコンセプトだと感じたでしょう。私たちはMTBF(mean time between failures)のようなさまざまな統計的な測定方法を利用できます。しかし、そうした方法は、時間経過とともに良くなる・悪くなるといったことしか教えてくれず、品質の現在地についてラフな情報しか示しません。
- コードの複雑さ。コードの複雑さを計測する方法はいくつもあります。そしてコードの複雑さはその他すべての計測にも影響するので、できるだけ複雑さを低く保つことが重要だと主張できます。いくつかのメトリクスは複雑さのために使用され、複雑さを下げるためにコードを書き換えさせるものもあるが、同時に可読性や保守性を下げてしまうものもあり、それは恐らく私たちが意図するものではありません。
上記の例に共通して言えることは、事後的にしか計測することができないということです。そのような計測は、進捗を測るのに重要かもしれませんが、実質的な改善を確実にするのに役立つものではありません。また、良い品質というものを定義するのが難しい一方で、それほど良くない品質に触れれば、簡単に見分けが付つくことも多いです。
繰り返されるテーマ
組込みシステムのソフトウェア開発は、その他のソフトウェア開発と共通することが多いです。しかし、それらに加えて、組込み開発では考慮することが多岐にわたります。高い信頼性の機能の実行、厳しい環境での動作、かなり遠隔地での動作、コイン電池での永久動作、デスクトップやサーバではまず起こらないシナリオなどです。
組込みソフトウェア開発は、最新のソフトウェア工学のトレンドと相性が良いとは限りません。プロジェクトの早い段階から基本的なルールを決めておくことで、より良い品質のソフトウェアを、より早く、より少ない不確実性で提供することができるようになるでしょう。
連載をとおして、私たちが常に立ち戻っていることがあります。それは、前もって準備をすることで、コードの品質、安全性、セキュリティ(これらの用語をどう定義するかは問いません)を高め、眠れない夜の回数を減らすことができるということです。
セキュリティから始める
今日から、全く新しい製品のアイデアを念頭に置いてスタートする、あるいは既にあるデザイン上に段階的に構築する場合、高い確率でデバイスに何らかのコネクティビティを追加することになるでしょう。WiFi、Bluetooth、ZigBee、または有線のいずれであるかは関係ありません。種々のCANが過去数年にわたりハッキングされたことを考えましょう。コネクティビティを追加する決断をした時点で、自分の未来がハッキング、クラック、デバイスの完全性の侵害に対して脆弱になっているのです。さらに、接続されたIoTデバイスに関して、世界中で施行されつつある地域ごとの法律にもさらされているのです。そうした法律の焦点は、個人情報の完全性と保護です。これと、ソフトウェアの完全性を確実にすることで、脆弱なデバイスから他のデバイスへ攻撃が飛び火することを防ぐことです。
プロジェクトの初期にするセキュリティ関連の決定は、製品の量産やデプロイなど製品ライフサイクル全体に影響があります。さらに、セキュリティ関連の決定を後期に変更することは非常に困難または不可能です。このため、たとえ今は意識的にセキュリティを無視するにしても、後日、その決定を見直すことになったときのために、自分を追い詰めないようにしておく必要があります。
静的解析しましょう
この連載で、色々な形で静的・動的解析について触れました。組込みの世界では、主にCやC++でソフトウェアを書いていますが、これらの言語はそのままでは信頼性の高いシステムを書くにはあまり適していないと言えます。それらはたくさんの未定義の動作や実装依存の動作を含みます。言い換えると、あるツールおよびハードウェアの組み合わせでは動くものでも、別のものでは動かないことがありえます。ベテランのプログラマでさえ、こうした言語の膨大な欠点を覚えておくことは難しいです。さらに単純な打ち間違えもコードをコンパイル可能なのに意図とは全く違うものへと変えてしまう可能性があります。
機能安全に対応する場合、MISRAのようなコーディング標準に準拠し、問題のあるプログラム構造を減らすことが強く推奨されていることをご存じでしょう。しかし、組込みシステム用のソフトウェア開発では、言語のサブセットを明確に定義して使用することで、奇妙で難解な言語ルールの結果としての不具合を取り除くことができると主張したいと思います。MISRAのガイドラインは素晴らしい始点で、コネクテッドシステム向けには、CERT Cも考慮するべきです。CWEも同様に有効なルールです。組込みに関するCWEのルールの多くが、MISRAまたはCERTでカバーされます。しかし、CWEの一覧は読んで損はないでしょう。
本稿で、これまでコード品質がとらえどころのないものと話してきたことを考えると、自動コード解析は、面倒なコード構造をすぐにハイライトすることによって、初日からコード品質を向上させるのに役立つものであると言えます。解析結果にもとづいて行動することで、未来に問題が生じる代わりに、その日に問題を取り除き具体的にコード品質を改善できるでしょう。
MISRAとプロジェクト独自のコード標準を組み合わせ、プロジェクトに適用することもプロジェクトの一貫性を保つ助けになるでしょう。例えば、命名規則、モジュール化のルール、グローバルに利用できる変数やデータ構造、volatileの使用方法などが含まれます。こうした明示的なルールと、望ましくは具体的なツールによるサポートがあることで、コード品質が劇的に改善されます。
解析機能を使うか、コード品質を失うか
コード品質と生産性を同時に改善しようとするなら、適切なツールを使用することが重要です。ある機能やプロセスの改善に新規のツールが必要かもしれません、しかしすでにツールが手元にある場合もあります。先見の明のあるマネージャが、すでに分析ツールなどを組織に提供してくれていることもあるかもしれません。
利用している開発環境で使用できるツールのマニュアルをよく読むことは、気づいていなかった機能を知るのに有効です。ユーザからのフィードバックで多いのは、デバッガについて高い確率で知らない機能があるというものです。マニュアルをよく読むというのは大事なことです。ほとんどの場合、自分がよく知っていてよく使うツールの機能や特徴の範囲内で快適に過ごすことができます。しかし、問題にぶつかったとき、事前にマニュアルを読んでいたことが報われることになります。
まとめ
本稿をお読みいただいた方は、組込みシステムのコード品質を攻略する上で何か新しい発見があったのではないでしょうか。コード品質を構成するものを明確に定義することは非常に困難です。一方で、質の悪いコードを書くのを最小限に抑えるためのツールやアイデアを数多くご紹介しています。
もうひとつ重要な点は、コード品質に焦点をあてることで、多かれ少なかれ自動的に、より安全で、よりセキュアで、より信頼性高く、より保守しやすいコードを作成できるということです。