web-dev-qa-db-ja.com

条件付きコンパイルは、製品の品質、セキュリティ、コードの複雑さにどのように影響しますか?

組み込みシステムなどのリソースに制約のある環境をターゲットとするソフトウェアライブラリは、条件付きコンパイルを使用して、本番環境で配布される最終的なバイナリから未使用の機能を削除することにより、消費者がスペースを節約できるようにします。

ユニークなバイナリを構築することのトレードオフは何ですか?確かに、ディスク、メモリ、CPUキャッシュのスペースが明らかに節約されています。時空間のトレードオフによってもたらされるパフォーマンスの利点。しかし、少なくとも当初は、テストや設計の可能性が高まるようです。

2つの異なるタイプの分岐を考慮するためだけでなく、コンパイラー条件構文がそのランタイム対応物よりも安全でないため(少なくともCでは)、その影響は従来のランタイムパスの複雑さとは異なるようです。

この質問を引き起こした具体的な例は、Busyboxが条件付きでコンパイルされた機能フラグを多用していることです。 https://git.busybox.net/busybox/tree/networking/httpd.c

7
Tomas Zubiri

一般的に言えば、条件付きコンパイルを使用すると複雑さが増し、セキュリティやその他の望ましい品質を実現することが難しくなります。この複雑さの一部は、一定量の変動を導入したい場合に不可欠です。もう1つの部分は偶発的なもので、条件付きコンパイルと利用可能なツールサポートの技術的な詳細に関連しています。

条件付きコンパイルなどの可変性情報でコードに注釈を付ける注釈ベースの可変性メカニズムの使用は、理解可能性とテスト容易性に影響します。

理解可能性の低下コードの特定の部分のコンテキストを理解して、理解できるようにするにはどうすればよいですか?コンパイラはどのように知るので、少なくとも型エラーなどがないことを確認できますか?問題は、構成可能な機能に関連するコードがコードベース全体に散在していることです。別の回答で述べられているように、この問題に対処するには一定の規律が必要ですが、根本的な問題を排除するものではありません。

テスト可能性の低下ソフトウェアがオプションのすべての組み合わせで機能することをどのようにして知っていますか?

これらの質問への答えは、実際にそれらを構築する前に、あなた、コンパイラ、または主流のテストツールがすべての可能なバリアントについて十分に推論することは不可能であるということです。問題は、結果として生じる組み合わせ爆発のために、すべての組み合わせを構築できないことです。変動性を意識した分析には概念がありますが、まだ広く採用されていません。

人間としては、ある程度まではコードを理解するときに限られた量の変動性を検討することができますが、問題に対処するための特定の技術的概念が存在しますが、多くのプロジェクトではまだ#ifdefの地獄です。

すでに述べたように、条件付きコンパイルの処理に役立つ広く利用可能なツールサポートはありません。

良いニュースは、研究の人々がこれらの問題を解決し、代替の変動メカニズムを調査することに取り組んでいることです。たとえば、コンポジションベースの変動メカニズムは、機能をモジュール化することにより、ローカルな推論に役立ちます(AOPだと思います)。有効な組み合わせの明示的な変動モデルに対して注釈をチェックすることにより、注釈ベースのメカニズムを使用するときにエラーを回避するのに役立つツールもあります。

一般的に変動性がある場合のテストに対処するために、さまざまな基準に基づいて代表的な組み合わせを選択するのに役立ついくつかのサンプリング方法があります。

変動性を意識した分析ツールもありますが、それらはまだ成熟した実装や業界での受け入れに欠けています。たとえば、多くの規格では製品ベースの分析が必要です。安全上重要なドメイン向け。現在、いつか成熟したツールへの道を見つけるかもしれない多くの概念があります。

3
Hyggenbodden

ユニークなバイナリを構築することのトレードオフは何ですか?確かに、ディスク、メモリ、CPUキャッシュのスペースが明らかに節約されています。時空間のトレードオフによってもたらされるパフォーマンスの利点。しかし、少なくとも当初は、テストや設計の可能性が高まるようです。

あなたが言ったように、リソースに制約のある環境を対象とした組み込みシステムについてのみ話していると仮定します。

  • cross-platformである必要があるプロジェクトの場合、不明な構造またはシンボルで異なるコンパイラーによってコンパイルエラーが発生するため、おそらく一意のバイナリを持つことは不可能です。
  • 実行時に他のものへの動的リンクが不可能の場合(これは対象のプロジェクトと環境に依存します)、条件付きコンパイルを使用するとこれを解決できる可能性があります。

IMO、あなたが正しく関心の分離およびコーディングのベストプラクティスを念頭に置いてプロジェクトを実装する場合、選択した手法(条件付きコンパイルの有無にかかわらず)に関係なく、プロジェクトは簡単かつ安全に実装および保守されます。

例:環境Aのコードがある場合は、環境Aを対象とするときにコンパイルされる特定のファイルに分離します。代わりに、そのシナリオの特定のファイルとフォルダーに一緒に属するラップ/グループスタッフ入れて#ifdef SOME_CONDITIONコード全体に広がります。

だから、あなたの質問に答えようとしています-条件付きコンパイルはどのように影響しますか:

  1. 製品の品質:正しく実行された場合(上記の例のように)、コードが取得されないため、製品の品質に影響しない可能性があります汚染されているか読みにくい(コードを個別のファイルに移動し、それらのファイルを何らかの条件に基づいてコンパイルするように構成したため、まったく逆)。さらに、testingの場合:(1)生成された異なる実行可能ファイルをテストする、または(2)同じバイナリをテストするが、構成ファイルを変更することによって、いくつかのシナリオをテストするのにどのくらいの違いがあるかわかりません。 performanceは、ランタイムアプローチがプログラムのすべての可能なオプションをチェックするため、増加する可能性がありますが、条件付きコンパイルプログラムには必要なバイナリのみが含まれます。
  2. セキュリティ:再度、正しく実行された場合、プログラムに、本来あるべきでない特定のコードが含まれていないことを確認できます。 (プロジェクトの理由にかかわらず)または、環境に必要な機能/権限のみを含むようにアプリケーションのバージョンを構築できます(例:特権の昇格などを回避するため)。また、プログラム内のオープンソースコードの使用を保護したい場合は、条件付きコンパイルを使用できます(例:何らかの理由で、プログラムの中にGPLコードを含めることができないプログラムの特定のバージョンを生成します)。
  3. コードの複雑さ:すべてのコード全体にifdefsを分散させると、明らかにますます複雑になり、最終的には維持できなくなります。それらを機能依存またはプラットフォーム依存のファイルに分離できれば、コードの記述やレビューの複雑さはそれほど影響を受けません。
2
Emerson Cardoso