Googleの C++スタイルガイド は、「例外を使用しません」と述べています。このスタイルでは、例外の使用に関してSTLに言及していません。 STLアロケーターは失敗する可能性があるため、コンテナーによってスローされた例外をどのように処理しますか?
Push_back()
やmap operator[]
などのSTLメソッドは、ステータスコードを返しません。彼らは、theyは例外を使用しないで、誰も例外を使用してはいけないと言っています。理論的根拠を見ると、彼らも書いている:
Googleの既存のC++コードのほとんどは例外を処理する準備ができていないため、例外を生成する新しいコードを採用することは比較的困難です。
通常のレガシー問題。 :-(
少なくともdo n'tコンテナによってスローされた例外を、少なくともアプリケーションレベルのコードで処理します。
私は2008年からC++で作業するGoogle検索のエンジニアです。STLコンテナを頻繁に使用しています。 vector :: Push_back()やmap :: operator []のような失敗にまでさかのぼる単一の大きな失敗やバグを個人的に思い出すことはできません。 「失敗」または「ダング、例外を使用した場合のみ、これは回避できたはずです。」プロセスがメモリ不足になることはありますか?はい。ただし、これは通常単純な間違いです(たとえば、誰かがプログラムに大きな新しいデータファイルを追加し、RAM割り当て)を増やすのを忘れた場合、または回復する良い方法がない致命的な障害私たちのシステムは、障害のあるディスク、宇宙線などを備えたマシンに対して堅牢になるように、すでにジョブを自動的に管理および再起動しますが、これもまったく同じです。
私が知る限り、ここで問題はありません。
theirコードで例外を使用しないことを意味すると確信しています。 cpplint script をチェックアウトすると、STLコンテナー(ベクター、リストなど)の正しいヘッダーが含まれていることを確認します。
とにかく、最新のオペレーティングシステムでは割り当てエラーを処理できません。パフォーマンスの最適化として、通常はメモリをオーバーコミットします。たとえば、malloc()
を呼び出してLinuxで非常に大きなメモリチャンクを要求すると、実際にバックアップに必要なメモリがなくても成功します。カーネルが実際にそれをバックアップするページを割り当てようとするのは、アクセスしたときだけであり、その時点で割り当てが失敗したと伝えるには遅すぎます。
そう:
特別な場合を除き、割り当ての失敗を心配しないでください。マシンのメモリが不足すると、それは致命的な障害になり、そこから確実に回復することはできません。
それでも、未処理の例外をキャッチし、e.what()
出力をログに記録してから、_throw
をログに記録することをお勧めします。それはあなたのために自動的に。
メモリ不足になったときにクラッシュに頼ることができないという上記の巨大なスレッドはすべて完了し、完全にゴミです。 C(++)標準では保証されない場合がありますが、現代のシステムでは、クラッシュするのはonlyであり、実行すると信頼できるものですメモリ不足。特に、アロケータからNULL
または実際にその他の表示を取得することに依存することはできません。C++例外までは含まれません。
ページ0にアクセスできる組み込みシステムを使用している場合は、その場所にアクセスできないページをマッピングすることで修正することを強くお勧めします。人間はどこにでもNULL
ポインターをチェックすることに依存することはできませんが、ページonceをマッピングすることで修正することができます。誰かがNULL
を見逃している可能性のあるすべての(過去、現在および未来)位置を修正します。
何らかのカスタムアロケーターを使用している可能性がある、またはオーバーコミットしないシステム上にいる可能性があると言って上記を修飾します(スワップのない組み込みシステムはその一例ですが、それだけではありません例)。その場合、多分youがメモリ不足状態を適切に処理できます。システム上で。しかし、一般的に21世紀には、チャンスを得る可能性は低いと思います。システムがメモリ不足であることを最初に知るのは、物事がクラッシュし始めるときです。
GoogleはSTLと例外についてこれを明示的に言及していることがわかりました(強調は私のものです):
独自のコードで例外を使用するべきではありませんが、例外はATLおよび一部のSTL(Visual C++に付属するものを含む)で広く使用されています。 ATLを使用する場合、_ATL_NO_EXCEPTIONSを定義して例外を無効にする必要があります。 STLで例外を無効にできるかどうかを調査する必要がありますが、そうでない場合は、コンパイラで例外を有効にしてもかまいません。 (これは、STLをコンパイルするためだけのものです。例外処理コードを自分で書くべきではありません。)
私はそのような決定は好きではありませんが(幸運なことに私はグーグルで働いていないのですが)、彼らは彼らの行動や意図についてははっきりしています。
Stl自体は、メモリ割り当てが失敗した場合にのみ直接スローされます。しかし、通常、実世界のアプリケーションはさまざまな理由で失敗する可能性があり、メモリ割り当ての失敗はそのうちの1つにすぎません。 32ビットシステムでは、メモリ割り当てエラーは発生する可能性があるため、無視すべきものではありません。したがって、メモリ割り当てエラーが発生しないという上記の議論全体は、無意味なものです。これを想定しても、2段階の初期化を使用して1つのコードを記述する必要があります。また、C++の例外処理は、64ビットアーキテクチャよりも前から存在していました。ここにグーグルが示したネガティブなプロフェッショナリズムをどれだけ堂々と尊敬し、質問に答えるだけでいいのかは定かではありません。 1997年頃にIBMがC++例外処理の意味を理解し、高く評価したIBMの一部の論文を覚えています。 Okプロフェッショナリズムは必ずしも成功の指標ではありません。したがって、例外処理を放棄することは、STLを使用する場合の問題だけではありません。C++を使用する場合は問題です。
質問で概説された仮定の下で、割り当ての失敗を処理する可能性は1つだけです。
アプリケーションは事前チェックを使用して発生しないことを保証できるので、このコンテキストでは、範囲外のインデックス例外はあまり興味深いものではありません。