7

我用 googletest 测试我的 C++ 代码。当由于使用错误索引访问 avector::_M_range_check而引发异常时,googletest 报告:std::vector

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

太好了,现在我也想知道哪个向量、哪个索引和哪个范围。如何轻松获取此信息,将测试代码保留在 googletest 单元测试用例中?

(我几乎从 Java 的旧IndexOutOfBoundsException开始很长时间......)

4

3 回答 3

9

如果您使用此命令行选项运行,那么您的异常将一直冒泡:

--gtest_catch_exceptions=0

在调试器中执行此操作将为您提供异常的确切堆栈跟踪。

于 2013-01-11T16:14:57.227 回答
7

此处不涉及 Google 测试。您的 C++ 标准库实现正在引发异常,由您的 C++ 标准库实现来决定使其异常的详细程度。

由于您遇到异常,我假设您使用std::vector::at的是std::vector::operator[]. 您可以采取几种可能的方法来获取更多信息。

首先,您可以将调用替换为at调用operator[](我个人认为at' 的异常抛出范围检查不是很有用,并且它确实有性能开销)并使用您的 C++ 标准库实现的迭代器调试。例如,对于 g++,如果我使用operator[]并编译 with-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不是虚拟的,所以必须通过wrapped调用at才能得到嵌套异常。

于 2013-01-11T16:29:16.333 回答