18

The following post discusses the type of a throw expression: In C++, if throw is an expression, what is its type?. I would like to clarify a more basic thing: why should throw be an expression and not a (non-expression) statement just like return in the first place? I mean, would anyone want to write something like auto x = throw std::runtime_error("Error message")?

Community
  • 1
  • 1
AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68

1 Answers1

11

If throw were a statement you couldn't use it with the conditional operator.

return success()
    ? computation()
    : throw std::runtime_error("oops");

Note : this may or may not have uses outside code obfuscation.

Edit : one useful case is inside C++11's strict constexpr functions which can only contain one instruction. Thanks @dyp for the insight !

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Another +1 for the note, which I would appreciate someone commenting on. It looks like I cannot vote twice :( – AlwaysLearning Jul 03 '15 at 07:43
  • Plus one, although worth noting perhaps that `throw std::runtime_error("oops")` is an expression of type `void` and it only works in a conditional due to some technical trickery that prevents me from answering this myself. – Bathsheba Jul 03 '15 at 07:50
  • @Bathsheba `return throw std::runtime_error("oops"), 0;` works too (thanks, comma operator from outer space !) – Quentin Jul 03 '15 at 07:52
  • @Quentin Could you please explain what the line of code in your comment does? – AlwaysLearning Jul 03 '15 at 08:00
  • 1
    @MeirGoldenberg the comma operator evaluates and discards its left operand, then evaluates and returns its right operand. Here, it will just throw the exception everytime, so this is not really useful *but* it's syntactically correct. – Quentin Jul 03 '15 at 08:03
  • 2
    *"Note : this may or may not have uses outside code obfuscation."* It is an important technique in C++11 constexpr functions. Those may only contain a return statement (plus declarations), so an if-statement is usually replaced by a ternary operator. Note that throwing exceptions is allowed inside constexpr functions; if the throw is invoked at compile-time, the compiler will report an error (which is what you'd want). – dyp Jul 03 '15 at 08:04
  • @dyp I thought about constexpr functions, but for some reason I was certain that throwing from one would be *really* bad. Well I'll edit this in then, thanks :) – Quentin Jul 03 '15 at 08:08
  • What is the type of this expression? – sbabbi Jul 03 '15 at 09:31
  • @sbabbi as stated in the linked question, the type of a throw-expression is `void`. – Quentin Jul 03 '15 at 09:32
  • 1
    On the other hand, `throw` being an expression predates `constexpr`. Therefore, I'm not sure that being able to put a `throw` into a conditional statement was enough of a motivation. – Morwenn Jul 03 '15 at 12:31
  • @Morwenn it is the only useful context that I know of which accepts `void` expressions. The other two being the `return` statement of a `void` function, and the comma operator. So, it was probably more of a lack of motivation to prohibiting it by making `throw` a statement. – Quentin Jul 03 '15 at 13:03