1

Okay, so I've been following a C++ guide, and I recently got to the section on exception handling. I couldn't get any of my code to work - it all produced some variation on the following error;

terminate called after throwing an instance of 'char const*'

Where "char const*" would be the type of whatever I was throwing.

I ctrl-c, ctrl-v 'ed the example code from the guide, and ran it to see if the error was my fault, or if there was something else going on. It produced the same error (above) as my code did.

Here's the code from the guide;

#include "math.h" // for sqrt() function
#include <iostream>
using namespace std;

// A modular square root function
double MySqrt(double dX)
{
    // If the user entered a negative number, this is an error condition
    if (dX < 0.0)
        throw "Can not take sqrt of negative number"; // throw exception of type char*

    return sqrt(dX);
}

int main()
{
    cout << "Enter a number: ";
    double dX;
    cin >> dX;

    try // Look for exceptions that occur within try block and route to attached catch block(s)
    {
        cout << "The sqrt of " << dX << " is " << MySqrt(dX) << endl;
    }
    catch (char* strException) // catch exceptions of type char*
    {
        cerr << "Error: " << strException << endl;
    }
}
Charles Noon
  • 559
  • 3
  • 10
  • 16

2 Answers2

4

Always catch absolute const exceptions: catch (const char const* strException).
It's neither intended, nor useful to put changes (write operations) to them. Not even on possible stack local copies.

Though what you're doing doesn't seem to be a very good idea. The convention for exceptions is these should implement a std::exception interface, that they could be caught in a canonical way. The standard compliant way would be

class invalid_sqrt_param : public std::exception {
public:
     virtual const char* what() const {
         return "Can not take sqrt of negative number";
     }
};

double MySqrt(double dX) {
    // If the user entered a negative number, this is an error condition
    if (dX < 0.0) { 
        // throw exception of type invalid_sqrt_param
        throw invalid_sqrt_param(); 
    }
    return sqrt(dX);
}

// Look for exceptions that occur within try block 
// and route to attached catch block(s)
try {
    cout << "The sqrt of " << dX << " is " << MySqrt(dX) << endl;
}
// catch exceptions of type 'const std::exception&'
catch (const std::exception& ex) {
    cerr << "Error: " << ex.what() << endl;
}

NOTE:
There's already a standard exception deigned for the case of invalid parameters passed to a function. Alternatively you can simply do

double MySqrt(double dX) {
    // If the user entered a negative number, this is an error condition
    if (dX < 0.0) { 
        // throw exception of type invalid_sqrt_param
        throw std::invalid_argument("MySqrt: Can not take sqrt of negative number"); 
    }
    return sqrt(dX);
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
2

As mentioned in the comments you're not catching const char* but char*.

If you change the appropriate line to const char* it will work like in this example.

You could add a catch(...) block like in this example but I would strongly advise against it as it could for example mask real problems you did not consider in the first place.

Style notes:

  • You should not #include "math.h" but #include <cmath> in cpp.
  • You should not use using namespace std; in real code (just pointing this out in case the "tutorial" didn't)
  • This tutorial smells, maybe you should find another source.
Community
  • 1
  • 1
Scis
  • 2,934
  • 3
  • 23
  • 37