What is this? catching polymorphic type X by value [-Wcatch-value=]

Viewed 12453

Does anyone know what the following compilation warning: catching polymorphic type ‘class std::out_of_range’ by value [-Wcatch-value=] warning means and how to correct it? I copied this code block literally out of Stroustrup's C++ 4th Edition. Thank you

#include <iostream>
#include <vector>
#include <list>
using std::vector;
using std::list;
using std::cout;

template <typename T>
class Vec : public vector<T> {
 public:
  using vector<T>::vector;  // constructor

  T& operator[](int i) { return vector<T>::at(i); }
  const T& operator[](int i) const { return vector<T>::at(i); }
};

int main(int argc, char* argv[]) {
  vector<int> v0 = {0, 1, 2};
  Vec<int> v1 = {0, 1, 2};

  cout << v0[v0.size()] << '\n';  // no error

  try {
    cout << v1[v1.size()];  // out of range
  } catch (std::out_of_range) {
    cout << "tried out of range" << '\n';
  }

  return 0;
}

Error:

$ g++ -Wall -pedantic -std=c++11 test69.cc && ./a.out
test69.cc: In function ‘int main(int, char**)’:
test69.cc:32:17: warning: catching polymorphic type ‘class std::out_of_range’ by value [-Wcatch-value=]
   } catch (std::out_of_range) {
                 ^~~~~~~~~~~~
0
tried out of range
2 Answers

If you look at the C++ Core Guidelines, you can find

E.15: Catch exceptions from a hierarchy by reference

This is exactly your case. By catching a value, you are effectively using just the base class of the exception thrown (regardless of the type actually thrown). Instead, catch by reference (or const reference, if you don't plan on modifying the exception), to retain the polymorphic behaviour.

Related