7

C++ コードを googletest でテストしています。vector::_M_range_checkが間違ったインデックスでアクセスされたために例外がスローされた場合std::vector、googletest は次のように報告します。

C++ exception with description "vector::_M_range_check" thrown in the test body.

よし、今度はどのベクトル、どのインデックス、どの範囲かを知りたい。テストコードを googletest ユニットテストケースに保持しながら、この情報を簡単に取得するにはどうすればよいですか?

(私は、古き良きIndexOutOfBoundsExceptionを使用して、Java を長く使い始めようとしています...)

4

3 に答える 3

9

このコマンドラインオプションを使用して実行すると、例外が完全に発生します。

--gtest_catch_exceptions=0

デバッガー内でこれを行うと、例外の正確なスタックトレースが得られます。

于 2013-01-11T16:14:57.227 に答える
7

GoogleTestはここには含まれていません。C ++標準ライブラリの実装は例外をスローします。例外をどのように冗長にするかを決定するのは、C++標準ライブラリの実装次第です。

std::vector::at例外が発生しているので、の代わりにを使用していると思いますstd::vector::operator[]。より多くの情報を取得するために取ることができるいくつかの可能なアプローチがあります。

まず、への呼び出しをへの呼び出しに置き換えatoperator[](個人的には、atの例外スロー範囲チェックが非常に役立つとは思わず、パフォーマンスのオーバーヘッドがあります)、C++標準ライブラリ実装のイテレータデバッグを使用できます。たとえば、g ++で、を使用operator[]してコンパイルし-D_GLIBCXX_DEBUG、の範囲チェックをオンにするoperator[]と、次のようなエラーが発生します。

/usr/include/c++/4.3/debug/vector:237:error: attempt to subscript container
    with out-of-bounds index 0, but container only holds 0 elements.

at次に、への呼び出しをへの呼び出しまたは同様のものに置き換えることができますtest_at:(未テスト)

template <typename T>
T& test_at(std::vector<T>& v, size_t n) {
    // Use Google Test to display details on out of bounds.
    // We can stream additional information here if we like.
    EXPECT_LT(n, v.size()) << "for vector at address " << &v;

    // Fall back to at, and let it throw its exception, so that our
    // test will terminate as expected.
    return v.at(n);
}
于 2013-01-11T16:08:07.367 に答える
0

vector::at(size_type n)out_of_range無効にスローすると文書化されていますn(23.2.3p17)。 out_of_rangeコンテナまたはインデックスに関する情報を保持しないため、atその情報が必要な場合はラップする必要があります。

template<typename T> struct my_vector: public std::vector<T> {
  using std::vector<T>;
  struct at_out_of_range: public std::out_of_range {
    my_vector *vector;
    size_type size;
    size_type n;
    at_out_of_range(my_vector *vector, size_type size, size_type n):
      std::out_of_range("at_out_of_range"), vector(vector), size(size), n(n) {}
  };
  reference at(size_type n) {
    try {
      return std::vector<T>::at(n);
    } catch(std::out_of_range &ex) {
      std::throw_with_nested(at_out_of_range(this, size(), n));
    }
  }
};

は仮想ではないため、ネストされた例外を取得するにはat、ラップされたものを呼び出す必要があります。at

于 2013-01-11T16:29:16.333 に答える