1

I have this code here:

int main()
{
   try // throw int
   {
      int a = 7;
      double b = 9.9;

      // throw int to show that only the double catch handler executes
      throw a < b ? a : b;
   } // end try
   catch ( int x ) // catch ints
   {
      cerr << "The int value " << x << " was thrown\n";
   } // end catch
   catch ( double y ) // catch doubles
   {
      cerr << "The double value " << y << " was thrown\n";
   } // end catch
} // end main

The output yields:

The double value 7 was thrown 

I am trying to understand why the int (a=7) was caught by the double handler.

In other words, why wasn't the int handler executed, even though it comes before the double handler?

Could it be due to some implicit conversion? If so, I'm not quite sure how the conditionals (a and b) are involved.

Any help would be grateful. Thanks!

  • 5
    The *type* of `a < b ? a : b` is a `double`. – Bathsheba May 14 '21 at 08:31
  • Yes, thank you. Can you help me understand why the type is double? – Adam Nguyen May 14 '21 at 08:35
  • Same rules as `a + b`. That's a `double` too. – Bathsheba May 14 '21 at 08:36
  • The duplicate says "the second and third operands must be lvalues of the same type" - so the `int` is implicitly converted to a `double`. – Ted Lyngmo May 14 '21 at 08:36
  • Because `common_type_t` is `double` – bolov May 14 '21 at 08:39
  • Yes, but from my understanding, ```a < b``` is not returned. Variables ```a``` or ```b``` is returned. With a ternary operator, ```a < b ? a : b``` is evaluated. Then ```a``` (an int) or ```b``` (a double) is returned. – Adam Nguyen May 14 '21 at 08:39
  • "The duplicate says "the second and third operands must be lvalues of the same type" - so the int is implicitly converted to a double. – Ted Lyngmo " This may be the answer! Thank you! Can you link me up a source or documentation for this? Thank you so much. – Adam Nguyen May 14 '21 at 08:40
  • That's the misconception. Nothing is really *retuned* in the sense that `return` returns something. Is more about the fact that either `a` or `b` is *evaluated* with the type of the result being the common type of `a` and `b`. – Bathsheba May 14 '21 at 08:41
  • AdamNguyen I think the link @user1810087 shared explains it – Ted Lyngmo May 14 '21 at 08:43
  • Thanks Ted. I guess where I was (and still to an extent) confused by is: Why is this expression ```throw a < b ? a : b;``` an lvalue I'm still trying to digest the answer provided in the link to apply it to my specific question. – Adam Nguyen May 14 '21 at 08:47
  • With an exerpt from that link: "In very broad and simple terms, an lvalue refers to an object in memory and an rvalue is just a value that may not necessarily be attached to an object in memory." This makes sense. I think I have an answer here albeit with some assumptions. With a throw, you are throwing an object (an lvalue must be an object while an rvalue doesn't have to be). – Adam Nguyen May 14 '21 at 08:52
  • But because it must be an object, it is then an lvalue. And if it is an lvalue, then: "For a conditional expression (?:) to be an lvalue (again, in broad and simple terms), the second and third operands must be lvalues of the same type." – Adam Nguyen May 14 '21 at 08:53
  • The question then becomes: Why is ```throw a < b ? a : b;``` an lvalue and not an rvalue? – Adam Nguyen May 14 '21 at 08:59
  • Okay, thank you for all your help, I really appreciate it. After digesting the answer provided in that link long enough, I think I've come to a satisfactory answer, provided above in my edit – Adam Nguyen May 14 '21 at 09:05
  • Try not to think to complex... if you would have `auto x = (a < b ? a : b);` and you want to replace `auto` with an specific type (while compiling, not running) what type would you choose? Probably the one which can represent 7 and 9.9?! [double](http://coliru.stacked-crooked.com/a/60e68b4f2233a742)?! – user1810087 May 14 '21 at 09:06
  • 2
    I think you're assuming that `throw a < b ? a : b` is equivalent to `if (a < b) throw a; else throw b;`, but it isn't. `a < b ? a : b` is an expression (which is why it's called a conditional expression), and all expressions have exactly one type. – molbdnilo May 14 '21 at 09:06
  • please note that questions are for the question while answers should go to answers. If I read it correctly your edits are merely a confirmation, that the duplicate did answer your question and I suggest you to remove them (usually I would just edit myself, but sometimes it is nicer to ask OP). Being closed as duplicate does not mean that your question is useless, but adding too many "EDIT"s makes it difficult to read and harder for future readers to make any use of it. See also https://meta.stackexchange.com/questions/127639/when-is-edit-update-appropriate-in-a-post – 463035818_is_not_an_ai May 14 '21 at 09:20
  • Okay, I removed the edits. That does make sense. And yes, Thank you molbdnilo, that was the conclusion I've come to. It comes down to the nuance of compile time and run time. – Adam Nguyen May 14 '21 at 09:33

0 Answers0