Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception Handling in C++ Terminate called after throwing an instance of 'char const*'

Tags:

c++

Error : Terminate called after throwing an instance of 'char const*'

terminate application has been required the Runtime to terminate it in an unusual way. Please contact the application's support team.

I'm not sure what's causing the compiler to crash when I do this. Any ideas? A bit new to programming.

#include <iostream>
#include <iomanip>

using namespace std;

//Template for Maximum

template <class X>
X Maximum(X arg1, X arg2)
{
    if (arg1 > arg2)
        return arg1;
    else
        return arg2;
}

//Template for Minimum

template <class M>
M Minimum(M arg1, M arg2)
{
    if (arg1 > arg2)
        return arg2;
    else
        return arg1;
}

/* Template for Divide(D arg1, D arg2) arg1: the dividend arg2: the divisor Description: 
Divides arg1 by arg2. If arg2 equals zero then an exception is thrown. */

template <class D>
D Divide(D arg1, D arg2)
{
    if (arg2 == 0) {
        throw "You cannot devide by zero! ";
    }
    return (arg1 / arg2);
}

int main()
{

    int a, b;
    float c, d;
    double e, f;
    a = 2;
    b = 22;
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(a, b) << "\tmax: " << Maximum(a, b) << endl;
    c = 4.7f;
    d = 2.97f;
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(c, d) << "\tmax: " << Maximum(c, d) << endl;

    e = 387.78;
    f = 387.7798;
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(e, f) << "\tmax: " << Maximum(e, f) << endl;
    e = 40;
    f = 0;
    try {
        cout << setprecision(4) << fixed << showpoint << "Divide: " << e << '/' << f << " = " << Divide(e, f) << endl;
    }
    catch (string exceptionString) {
        cout << exceptionString;
    }
    system("pause");
    return 0;
}
like image 227
Chad Avatar asked Oct 23 '17 14:10

Chad


1 Answers

A string literal is not a std::string. You throw the former, but try to catch the latter. Despite the fact a std::string may be constructed from a string literal, it won't happen in a catch clause. The conversions which are allowed in a catch clause are detailed in [except.handle]/3:

A handler is a match for an exception object of type E if:

  • The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifiers), or
  • the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
  • the handler is of type cv T or const T& where T is a pointer or pointer to member type and E is a pointer or pointer to member type that can be converted to T by one or more of
    • a standard pointer conversion not involving conversions to pointers to private or protected or ambiguous classes
    • a function pointer conversion
    • a qualification conversion, or
  • the handler is of type cv T or const T& where T is a pointer or pointer to member type and E is std​::​nullptr_­t.

And neither of which applied for the case of literal -> std::string conversion.

Which ultimately results in that exception being uncaught, and the run-time calling std::terminate as is supposed to happen with uncaught exceptions.

In general, it's best to throw a dedicated exception type (which may be part of a hierarchy), such that the very type name communicates the error that occurred. This will allow handling the error in more robust ways, if a handler (or a set of handlers) need to be written.

If you don't want to follow the standard practice for some reason, you must make the conversion be one of those mentioned in the above bullets. You can either:

  1. Throw a std::string literal, like "You cannot devide by zero!"s (note the s suffix).
  2. Catch a const char*.
like image 176
StoryTeller - Unslander Monica Avatar answered Oct 07 '22 01:10

StoryTeller - Unslander Monica