メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

キャッチされていない例外

例外がキャッチされないまま main 関数や他のエントリポイント関数に伝播

説明

このチェックは、以下の問題を調査します。

  • キャッチされていない例外が main 関数や他のエントリポイント関数に伝播する。

  • 例外がグローバル変数のコンストラクターでスローされ、キャッチされない。

  • 例外がデストラクター呼び出しまたは delete 式でスローされる。

  • 以前のスロー式が catch ステートメントによって処理される前に例外がスローされる (catch ステートメント パラメーターの構築時など)。

  • noexcept 仕様違反。たとえば、noexcept(true) を使用して宣言された関数は例外をスローしないはずなのに、関数本体で例外がスローされる。

これらの状況では、C++ 規格に従って、関数 std::terminate が呼び出され、予期しない結果が発生する可能性があります。

標準テンプレート ライブラリの関数については、それらの関数が Polyspace でスタブ化され、関数から例外がスローされるかどうかがチェックされない場合も、[キャッチされていない例外] チェックがグリーンになることに注意してください。

すべて展開する

#include <vector>
using namespace std;

class error {};

class initialVector {
private:
  int sizeVector;
  vector<int> table;
public:
  initialVector(int size) {
    sizeVector = size;
    table.resize(sizeVector);
    Initialize();
  }
  void Initialize();
  int getValue(int number) throw(error);
};

void initialVector::Initialize() {
  for(int i=0; i<table.size(); i++)
    table[i]=0;
}

int initialVector::getValue(int index) throw(error) {
  if(index >= 0 && index < sizeVector)
    return table[index];
  else throw error();
}

void main() {
    initialVector *vectorPtr = new initialVector(5);
    vectorPtr->getValue(5);
}

この例では、メソッド initialVector::getValue の呼び出しで例外がスローされます。この例外がキャッチされないまま main 関数に伝播し、レッドの [キャッチされていない例外] チェックが発生します。

class error {
public:
  error() {  }
  error(const error&) { }
};


void funcNegative() {
  try {
    throw error() ;
  } catch (error NegativeError) {
  }
}

void funcPositive() {
  try {
  }
  catch (error PositiveError) {
  /* Gray code */
  }
}

int input();
void main()
{
    int val=input();
    if(val < 0)
        funcNegative(); 
    else
        funcPositive(); 
}

この例では以下のようになります。

  • funcNegative の呼び出しは例外をスローします。ただし、例外は try ブロック内に配置され、対応するハンドラー (catch 句) によってキャッチされます。main 関数に対する [キャッチされていない例外] チェックは、例外が main に伝播しないため、グリーンで表示されます。

  • funcPositive の呼び出しは try ブロック内で例外をスローしません。したがって、try ブロックに続く catch ブロックはグレーで表示されます。

class error {
};

class X
{
public:
  X() {
    ;
  }
  ~X() {
    throw error();
  }
};

int main() {
  try {
    X * px = new X ;
    delete px;
  } catch (error) {
    assert(1) ;
  }
}

この例では、delete 演算子はデストラクター X::~X() を呼び出します。デストラクターは、デストラクター本文にレッド エラーとして表示され、delete 演算子に赤の破線として表示される例外をスローします。例外は catch ブロックに伝播しません。例外に続くコードは検証されません。この振る舞いにより、デストラクターは例外をスローしてはならないという要件が遵守されます。

ブラックの assert ステートメントは、例外が catch ブロックに伝播していないことを示します。

#include<stdio.h>
#define SIZE 100

int arr[SIZE];
int getIndex();

int runningSum() {
  int index, sum=0;
  while(1) {
    index=getIndex();
    if(index < 0 || index >= SIZE)
      throw int(1);
    sum+=arr[index];
  }
}

void main() {
    printf("The sum of elements is: %d",runningSum());
}

この例では、関数 runningSumindex が範囲 [0,SIZE] 外にある場合にのみ例外をスローします。通常、if ステートメントの命令により生じるエラーは、レッドではなくオレンジです。if ステートメントを含まない別の実行パスがエラーを生成しないため、エラーはオレンジになっています。ここでは、ループが無限であるため、ループの外に抜ける別の実行パスは存在しません。if ステートメントの例外を介してのみ、ループ外に抜けられます。したがって、[キャッチされていない例外] エラーはレッドになります。

#include <string>

void f() { throw; }        //rethrow not allowed - an error is raised here
void main() {
    try {
        throw std::string("hello");
     }
    catch (std::string& exc) {
        f();                    
    }
}

この例では、catch ブロック外の関数 f() で例外が再スローされます。例外引数を指定しないでそれ自体が throw を呼び出すと、再スローが発生します。再スローは、例外を try-catch シーケンスの外部に伝播するために、通常 catch ブロックの "内部" で使用されます。Polyspace® Code Prover™ では、catch ブロックの "外部" での再スローをサポートしないため、[キャッチされていない例外] ではレッド エラーが生成されます。

チェック情報

グループ: C++
言語: C++
頭字語: EXC