Basic question regarding exception handling

Does it make any sense to have a throw statement in a function without a catch? I found it in a solution set, but I'm getting "terminating with uncaught exception of type int" when I run the program, so I suspect it's wrong.


1
2
3
4
5
6
7
8
9
double nFacRobust(unsigned int n) {
 
if (n > NFAK_LIMIT) {
       throw n;
}
else {
       return (nFac(n)); //just a function calculating n factorial
 }
}
> Does it make any sense to have a throw statement in a function without a catch?
That's the usual thing to do.
A function doing the throwing by definition can't deal with the error, so catching is pointless.

> but I'm getting "terminating with uncaught exception of type int"
Well somewhere, you need a catch in the call hierarchy all the way back to main.

The "uncaught" bit means that either you had no try/catch anywhere, or those try/catches you do have don't catch int exceptions.
Ok, so you can basically have a function where a potential exception is thrown, and place it inside another function with a catch-statement?
Bingo. So long as you document your code properly, so that whoever is going to call on your functions knows that they need to be ready to catch exceptions, and you document what can be thrown and what it means, good to go.
Something like this, crudely written to show how to make it work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>

const unsigned NFAK_LIMIT = 100;

unsigned nFac(unsigned n)
{
   unsigned return_value = 0;

   // do the factorial stuff and get an actual factorial

   return return_value;
}

unsigned int nFacRobust(unsigned int n)
{
   if (n > NFAK_LIMIT)
   {
      throw n;
   }
   else
   {
      return (nFac(n));
   }
}

int main()
{
   unsigned some_big_number = 125;
   try
      {
         nFacRobust(some_big_number);
      }

      catch (...)
      {
         // dealing with the consequences of too big a number for your function to deal with

         std::cout << "Hey, you wanted a bigger factorial than I can handle!\n";
      }
}
Hey, you wanted a bigger factorial than I can handle!

If I were doing this I'd restructure it a bit so the error checking is done within the nFac() function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

const unsigned NFAK_LIMIT = 100;

unsigned nFac(unsigned n)
{
   unsigned return_value = 0;

   if (n > NFAK_LIMIT)
   {
      throw n;
   }
   else
   {
      // do the factorial stuff and get an actual factorial
   }

   return return_value;
}

int main()
{
   unsigned some_big_number = 125;
   try
      {
         nFac(some_big_number);
      }

      catch (...)
      {
         // dealing with the consequences of too big a number for your function to deal with

         std::cout << "Hey, you wanted a bigger factorial than I can handle!\n";
      }
}
Another version that leverages throwing the number passed into the function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>

const unsigned NFAK_LIMIT = 100;

unsigned nFac(unsigned n)
{
   unsigned return_value = 0;

   if (n > NFAK_LIMIT)
   {
      throw n;
   }
   else
   {
      // do the factorial stuff and get an actual factorial
   }

   return return_value;
}

int main()
{
   unsigned some_big_number = 125;

   try
   {
      nFac(some_big_number);
   }

   catch (unsigned e)
   {
      // dealing with the consequences of too big a number for your function to deal with

      std::cout << "Hey, " << e << " would create a bigger factorial than I can handle!\n";
   }
}
Hey, 125 would create a bigger factorial than I can handle!
Last edited on
Topic archived. No new replies allowed.