まず、この質問があまりにもオープンエンドでないことを願っています。コーディング標準/ポリシー、ライブラリ/API の比較などで使用するための要素として、形容詞「ライブラリセーフ」の正式または少なくとも半正式な定義を確立しようとしています。定義の一部としてベスト プラクティスについての私自身の見解やその他の恣意的な見解を押し付けないようにするために、過度に制限的な定義は避けたいと思います。私が言いたいことの例として、静的ストレージ期間の非 const 修飾オブジェクトにアクセスするコード、または他のプロセスグローバル状態 (シグナル処理など) を変更するコードをライブラリセーフでないと見なすことは、おそらく実用的な定義ですが、必要以上に厳格です。
私が捉えようとしている重要なプロパティは、コードを「ライブラリセーフ」と言うときに理解されると思いますが、次のとおりです。
ライブラリ コードを使用する同じコードの複数のインスタンス (再帰またはスレッド) を意味するか、ライブラリ コードを使用するプログラムの完全に分離した部分を意味するかに関係なく、同じプロセスでライブラリ コードの複数の「ユーザー」を持つことができます。これらのユーザーは必要ありません。お互いのつま先を踏む。
インターフェイス コントラクトに記載されている場合を除き、呼び出し元に「属する」状態を変更しない。
私がこの質問に適していると考える回答の種類は、この概念を定義するための同様の過去の試みへの言及、定義をまとめるための強力なアイデア、またはこの概念を正確に定義しようとする試みは無駄であるという説得力のある議論です.
ところで、この C、C++、および POSIX にタグを付けたのは、これらのコンテキストにそのような定義を適用することに最も関心があるためです。他の言語のコンテキストではあまり面白くないかもしれません。たとえば、非常に純粋な関数型言語では、すべてのコードはおそらく「ライブラリセーフ」と見なされるべきです。
提案された定義:
次のようなプログラム A と B が存在する場合、ライブラリ L はライブラリ安全ではありません。
- A と B は入力を受け付けません。
- A と B は、終了ステータス以外の出力を生成しません。
- A と B は、未定義の動作を呼び出しません。
- A と B には、グローバル状態を変更する L 以外のコードは含まれていません。
- A と B を 1 つのプログラムに結合し、必要に応じて L 以外の関数またはオブジェクトの名前を変更して衝突を回避し、A と B のメイン関数がそれぞれ独自のスレッドで実行されるようにすると、プログラムは未定義の動作を呼び出したり、出力が異なったりします。 A と B を別々に実行した出力から。