-1

I know that when catching an exception by value, copy constructor is called, but is there anything bad when catching by value or not by reference and can you give a specific example when the bad thing happens if catching by value? (I mean except the time needed for copy constructor to execute, but as exceptions happen rarely, it is not important). I heard there is something to do with slicing problem, but I cannot come out with any idea when this can cause damage/problem.

Andrey Rubliov
  • 1,359
  • 2
  • 17
  • 24
  • 2
    "_I heard there is something to do with slicing problem, but I cannot come out with any idea when this can cause damage/problem_" Do you know what object slicing _is_? – Algirdas Preidžius Oct 30 '17 at 14:51
  • throw by value, catch by const reference. Don't copy the caught exception, re-throw with `throw` or `std::rethrow_with_nested`. That way, no slicing. – Richard Hodges Oct 30 '17 at 14:52
  • Thanks for this, I always throw by val and catch by ref, but I was asked this question in a C++ interview :( – Andrey Rubliov Oct 30 '17 at 14:58
  • I do know what object slicing is, but I could not create an example of this happening when catching by value. If you have class A1 deriving from E1 and you throw E2 and catch E1 by value, then what bad happens? If after you caught E1 by value you do: "throw" it throws the original exception, not your new E1 object. Now if you throw E2 and catch E2 by value - what is bad here? – Andrey Rubliov Oct 30 '17 at 15:01

1 Answers1

3

Other than (1) the potential for object slicing (which is very hazardous) and (2) overheads in taking a value copy, you lose the ability to modify the exception in some way:

catch (Foo ex){
    ex.embellishWithMoreDetails(/*whatever*/);
    throw; // rethrows the caught, not the copied exception by reference.
}

and that could make your program unwieldy.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Bathsheba, thanks for this, but where is the problem in your example? Your empty "throw" re-throws the original exception and not your new object. – Andrey Rubliov Oct 30 '17 at 15:02
  • `throw` will throw the exception that was deep-copied. It does **not** throw `ex`. – Bathsheba Oct 30 '17 at 15:03
  • Sorry, I just checked this with printing the pointers and no, throw throws the original instance, not the copied one. If you need to throw the copied one you need to throw it explicitly. – Andrey Rubliov Oct 30 '17 at 15:17
  • That's what I'm saying ;-) I've made that clear in the program comment. – Bathsheba Oct 30 '17 at 15:18
  • So then everything is good. You catch ex by value, copy it and use it, then you call throw, it throws the original exception, so it can be caught in other places, i.e. from the calling function. Don't see any slicing problem here – Andrey Rubliov Oct 30 '17 at 15:20