AUTOSAR C++14 Rule A15-2-1
Constructors that are not noexcept shall not be invoked before program startup
説明
ルール定義
Constructors that are not noexcept shall not be invoked before program startup.
根拠
C++ では、コンパイラが次の手順に従って例外に対処します。
コンパイラは、現在のスコープまたは上位スコープ内のハンドラーと例外を一致させようとします。
例外がハンドラーと一致すると、そのハンドラーが例外を受け入れ、スタックのアンワインドを開始します。スタックのアンワインド中は、例外を発生させるスコープから、外側のスコープへと、逆の順序でプログラム実行が移動します。次にプログラム実行は、まだ破棄されていないスタック上の変数ごとにデストラクターを呼び出します。スタックのアンワインド後は、トリガーされたハンドラーの直後の行からプログラム実行が再開します。
例外がハンドラーと一致しなかった場合は、コンパイラが処理系定義に従って実行を終了させます。つまり、プログラム終了の具体的なプロセスは、使用しているソフトウェアとハードウェアの特定の組み合わせに応じて異なります。たとえば、コンパイラが
std::terminate()を呼び出すと、std::abort()が呼び出され、実行が異常終了される場合があります。実装に基づいて、プログラムが中止される前にスタックがアンワインドされない可能性があります。プログラムが終了する前にスタックがアンワインドされなかった場合は、スタック内の変数のデストラクターが呼び出されず、リソース リークやセキュリティの脆弱性につながります。
プログラムの起動前に、静的オブジェクトまたはグローバル オブジェクトのコンストラクターが呼び出され、オブジェクトを構築して初期化します。このようなコンストラクターが例外を発生させた場合は、コンパイラがスタックをアンワインドせずにコードの実行を異常終了させる可能性があります。静的オブジェクト obj のコンストラクターが例外を引き起こす可能性がある次のコードについて考えます。
class A{
A(){
//...
}
};
static A obj;
main(){
//...
}main() が開始する前に、静的オブジェクト obj は A() を呼び出すことにより構築されます。A() はプログラムの起動前に呼び出されるため、どの例外ハンドラーも A() によって発生した例外と一致しません。実装に基づいて、このような例外はスタックをアンワインドせずにプログラムを終了させる可能性があり、メモリ リークやセキュリティの脆弱性につながります。静的オブジェクトまたはグローバル オブジェクトのコンストラクターによって発生された例外は例外ハンドラーと一致しないため、このようなコンストラクターは noexcept と宣言します。
Polyspace 実装
Polyspace® は、静的オブジェクトまたはグローバル オブジェクトの非 noexcept コンストラクターが直接呼び出されるステートメントにフラグを設定します。また、非準拠のコンストラクターを強調表示します。
トラブルシューティング
ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。
例
チェック情報
| グループ: Exception Handling |
| カテゴリ: Required、Automated |