1

I have created one exception in a function like so:

void testing(int &X)
{
....
X=...
if (X>5)
throw "X greater than 5!"
}

and then in main.cpp

try
{
int X=0; 
testing(X);
}

catch (const char *msgX)
{
....
}

But now I would like to also introduce Y as X. and the prototype of testing will be :

void testing(int &X, int &Y)

My question, how can I throw two exceptions, in which if X>5, I throw an exception regarding X and if Y>10, I throw another exception about Y and I catch them all at the end in my main program?

Crowman
  • 25,242
  • 5
  • 48
  • 56
MelMed
  • 1,702
  • 5
  • 17
  • 25
  • hint: create a specific class to represent each type of exception and then throw an instance of each, then you can catch them individually... – Nim Oct 17 '13 at 13:37
  • I would not understand why you put -1? – MelMed Oct 17 '13 at 13:38
  • 1
    You may be interested in: http://stackoverflow.com/questions/134569/c-exception-throwing-stdstring – newfurniturey Oct 17 '13 at 13:39
  • 2
    If I understand correctly what you want to do, then it is not possible. When you throw an exception, control transfers to the catch handler, so the rest of the function that threw it is not executed. You can't throw multiple exceptions from a single call to `testing`. – Steve Jessop Oct 17 '13 at 13:44

3 Answers3

2

In C++ it is impossible to have two exceptions "in flight" at the same time. If that condition ever arises (e.g. by a destructor throwing during stack unwinding), the program is terminated (with no way to catch the second exception).

What you can do is make a suitable exception class, and throw that. For example:

class my_exception : public std::exception {
public:
    my_exception() : x(0), y(0) {} // assumes 0 is never a bad value
    void set_bad_x(int value) { x = value; }
    void set_bad_y(int value) { y = value; }
    virtual const char* what() {
        text.clear();
        text << "error:";
        if (x)
            text << " bad x=" << x;
        if (y)
            text << " bad y=" << y;
        return text.str().c_str();
    }
private:
    int x;
    int y;
    std::ostringstream text; // ok, this is not nothrow, sue me
};

Then:

void testing(int &X, int &Y)
{
    // ....
    if (X>5 || Y>10) {
        my_exception ex;
        if (X>5)
            ex.set_bad_x(X);
        if (Y>10)
            ex.set_bad_y(Y);
        throw ex;
    }
}

Anyway you should never throw raw strings or integers or the like--only classes derived from std::exception (or perhaps your favorite library's exception classes, which hopefully then derive from there, but may not).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • [std::string in exceptions](http://stackoverflow.com/questions/15831029/not-using-stdstring-in-exceptions) – user1810087 Oct 17 '13 at 13:51
  • @itwasntpete: yup, that's why I wrote the comment in the code about nothrow. – John Zwinck Oct 17 '13 at 14:15
  • When writing throw " ..." is it possible to check at the end if there is something to throw or not before moving to the main program? – MelMed Oct 17 '13 at 14:54
0

You can throw different exception types or you can through the same exception type with different content.

struct myexception : public std::exception
{
   std::string description;
   myexception(std::string const & ss) : description(ss) {}
   ~myexception() throw () {} // Updated
   const char* what() const throw() { return description.c_str(); }
};

void testing(int &X, int &Y)
{
   if (X>5)
      throw myexception("X greater than 5!")
   if (Y>5)
      throw myexception("Y greater than 5!")
}

try
{
   int X=0; 
   testing(X);
}
catch (myexception const & ex)
{

}
Marius Bancila
  • 16,053
  • 9
  • 49
  • 91
  • 1
    [std::string in exceptions](http://stackoverflow.com/questions/15831029/not-using-stdstring-in-exceptions) – user1810087 Oct 17 '13 at 13:51
  • There is, of course, nothing to stop you doing `if ( X > 5 && Y > 5 ) throw myexception("Both X and Y are too large.");` first. – Crowman Oct 17 '13 at 13:58
0

Here is a sketch:

class x_out_of_range : public std::exception {
  virtual const char* what() { return "x > 5"; }
};

class y_out_of_range : public std::exception {
  virtual const char* what() { return "y > 10"; }
};

Now in your function:

if (x > 5)
  throw x_out_of_range();

:

if (y > 10)
  throw y_out_of_range();

Now your catch code:

try
{
  :
}
catch (x_out_of_range const& e)
{
}
catch (y_out_of_range const& e)
{
}

NOTE: in any case, you can only throw one exception from the function...

miken32
  • 42,008
  • 16
  • 111
  • 154
Nim
  • 33,299
  • 2
  • 62
  • 101