メインコンテンツ

MISRA C++:2008 Rule 15-1-3

An empty throw (throw;) shall only be used in the compound- statement of a catch handler.

説明

ルール定義

An empty throw (throw;) shall only be used in the compound- statement of a catch handler. 1

根拠

空の throw ステートメント (throw;) を使用すると、例外オブジェクトが現在のスコープ内に存在するかどうかがコンパイラによって確認されます。現在のスコープ内に例外オブジェクトが含まれている場合には、現在の例外を含む一時オブジェクトがコンパイラにより報告されます。現在のスコープに例外オブジェクトが含まれていない場合は、コンパイラが std::terminate() を暗黙的に呼び出します。関数 std::terminate() は処理系定義の方法でプログラム実行を終了します。つまり、プログラム終了の具体的なプロセスは、使用しているソフトウェアとハードウェアに応じて異なります。たとえば、std:terminate()std::abort() を呼び出してスタックのアンワインドを行わずに実行を異常終了する可能性があり、リソース リークとセキュリティの脆弱性につながります。

ベスト プラクティスは、try-catch 構造の catch ブロックでのみ空の throw ステートメントを使用することです。これにより、例外処理を複数の catch ブロックに分散できます。例外が含まれていない可能性のあるスコープでは、空の throw ステートメントの使用を回避します。

Polyspace 実装

Polyspace® は、空の throw ステートメントが catch ブロック内にない場合に、この throw ステートメントにフラグを設定します。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include <iostream>       
#include <typeinfo>       
#include <exception>      

void handleException()//function to handle all exception
{
	try {
		throw; // Noncompliant
	}
	catch (std::bad_cast& e) {
		//...Handle bad_cast...
	}
	catch (std::bad_alloc& e) {
		//...Handle bad_alloc...
	}
	catch(...){
		//...Handle other exceptions
	}
}

void f()
{
	try {
		//...something that might throw...
	}
	catch (...) {
		handleException();
	}
}

この例では、関数 handleException() が空の throw ステートメントを使用して現在の例外を報告し、それを適切な catch ブロックに送っています。この例外処理のデリゲート方法が意図されているように機能するのは、関数 handleException()catch ブロック内部から呼び出される場合だけです。例外が含まれていない他のスコープでこの関数が呼び出される場合、空の throw ステートメントが原因で、プログラムが突然終了することがあります。Polyspace は空の throw ステートメントにフラグを設定します。

#include <iostream>       
#include <typeinfo>       
#include <exception> 
void foo()//function to handle all exception
{
	try {
		//...
	}
	catch (std::bad_cast& e) {
		//...Handle bad_cast...
	}
	catch (std::bad_alloc& e) {
		//...Handle bad_alloc...
	}
	catch(std::exception& e){
		//...Handle std::exceptions
		// if exception cannot be handled
		// throw it again
		throw;//Compliant
	}
}

int main(){
	try{
		foo();
	}
	catch(...){
		
	}
}

この例は、空の throw ステートメントの準拠使用を示しています。関数 foo には、特定の例外を処理する try-catch 構造が含まれています。報告された例外を処理できない場合、foo は空の throw ステートメントを使用してこの例外を未処理の例外として再び報告します。main で関数 foo が呼び出され、foo から発生した未処理の例外はすべて、汎用 catch(...) ブロックで処理されます。空の throw ステートメントを使用することで、foo および main の catch ブロックに例外の処理が分散されます。この場合、同じスコープ内に例外がある場合にのみ空の throw ステートメントが実行されます。これは、空の throw ステートメントが catch ブロック内にあるためです。Polyspace はこれにフラグを設定しません。

チェック情報

グループ: Exception Handling
カテゴリ: 必要

バージョン履歴

R2013b で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.