Program executed on Cygwin does not report a thrown exception
Asked Answered
R

3

6

When I run a simple program shown below, I get different terminal output on Cygwin and Ubuntu OS.

#include    <cstdio>
#include    <stdexcept>
#include    <cmath>

using namespace std;

double square_root(double x)
{
    if (x < 0)
        throw out_of_range("x<0");

    return sqrt(x);
}

int main() {
    const double input = -1;
    double result = square_root(input);
    printf("Square root of %f is %f\n", input, result);
    return 0;
}

On Cygwin, unlike Ubuntu, I do not get any message indicating that an exception was thrown. What could be the reason for that? Is there something I need to download for Cygwin so that it deals with exceptions as it is supposed to?

I am using Cygwin version 1.7.30 with GCC 4.9.0 . On Ubuntu, I have version 13.10 with GCC 4.8.1 . I doubt that difference in compilers matters in this case.

Role answered 25/6, 2014 at 7:15 Comment(1)
Faced with the same problem, thank you.Spooky
M
4

Since you do not catch the exception, behaviour depends on the implementation/runtime. This seems to be implemented differently for Linux and cygwin.

You should catch the exception yourself, or use something as explained in the answers to this question.

Magness answered 25/6, 2014 at 7:26 Comment(0)
O
7

The behaviour is not defined for this case - you are relying on the "kindness" of the C++ runtime to issue some text for the "you didn't catch the exception", which the glibc of Linux indeed does, and apparently the Cygwin does not.

Instead, wrap your main code in a try/catch to handle the throw.

int main() {
    try
    {
        const double input = -1;
        double result = square_root(input);
        printf("Square root of %f is %f\n", input, result);
        return 0;
    }
    catch(...)
    {
        printf("Caught exception in main that wasn't handled...");
        return 10;
    }
}

A nice solution, as suggested by Matt McNabb is to "rename main", and do somethting like this:

int actual_main() {
    const double input = -1;
    double result = square_root(input);
    printf("Square root of %f is %f\n", input, result);
    return 0;
}

int main()
{
    try
    {
        return actual_main();
    }
    catch(std::exception e)
    {
         printf("Caught unhandled std:exception in main: %s\n", e.what().c_str());
    }
    catch(...)
    {
         printf("Caught unhandled and unknown exception in main...\n");
    }
    return 10;
}

Note that we return a different value than zero to indicate "failure" - I expect that at the very least, Cygwin does that already.

Oralee answered 25/6, 2014 at 7:28 Comment(2)
There are lots of different options. Exceptions does not HAVE to be related to std::exception, so ultimately you need a catch(...) to ensure that ANY exception is caught. I have included such a solution.Oralee
I tried to set std::set_terminate() to my own function, but that function doesn't seem to get called. Shouldn't that work in C++11?Officious
M
4

Since you do not catch the exception, behaviour depends on the implementation/runtime. This seems to be implemented differently for Linux and cygwin.

You should catch the exception yourself, or use something as explained in the answers to this question.

Magness answered 25/6, 2014 at 7:26 Comment(0)
S
0

One way to debug this type of C++ error is by simply just rewriting it in C, then translating it back into C++. C is simpler so translating it to C should eliminate your problem.

Shotgun answered 2/2, 2020 at 6:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.