2

I was trying to demonstrate exception handling and came across an oddity I can't solve. The problem arises in the following code:

#include <iostream>
#include <cmath>
#include <stdexcept>

using namespace std;

double sqrt(double x) {                                                         
    if ( x < 0 ){
        throw invalid_argument("sqrt received negative argument");
    }
    return sqrt(x);
}


int main(int argc, char *argv[]) {

    try {
        double s = sqrt(-1);
    }
    catch (const exception& e) {
        cout << "Caught " << e.what() << endl;
    }
    return 0;
}

The code fails:

 terminate called after throwing an instance of 'std::invalid_argument'
 what():  sqrt received negative argument
 ./dostuff.sh: line 8:  3472 Aborted                 (core dumped) ./may_22.exe

If, however, I either change the name of the sqrt function I write to "mySqrt", or remove the header, the exception is properly caught. Any idea what is causing this?

I'm compiling via

 g++ -g -Wall -std=c++0x -Weffc++   may_22.cpp -o may_22.exe

with g++ (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1

EDIT: To clarify, this does not seem like a namespace issue. The code is clearly calling my sqrt function, as shown by the exception message.

EDIT 2: This code still fails to handle the exception for me.

#include <iostream>
#include <cmath>
#include <stdexcept>

double sqrt(double x) {
    if ( x < 0 ){
        throw std::invalid_argument("sqrt received negative argument");
    }
    return std::sqrt(x);                                                        
}

int main(int argc, char *argv[]) {

    try {
        double s = sqrt(-1);
    }
    catch (std::exception& e) {
        std::cout << "Caught " << e.what() << std::endl;
    }

    return 0;
}
  • I don't see why it's a duplicate. Even if it's in `std` I don't understand why exception is thrown and not caught – RiaD May 22 '14 at 23:36
  • Assuming the name isn't a problem, if you didn't throw an exception wouldn't the function be infinitely recursive? Your code generates a linker error on Visual Studio but works fine there and [here](http://ideone.com/uziiN9) if the function name is changed. – Retired Ninja May 22 '14 at 23:39
  • Well, technically the link is correct: this is evidently causing undefined behavior, so the compiler is free to do as it pleases (such as fail to catch an exception properly). – user3667059 May 22 '14 at 23:40
  • I think the question should be unlocked as there is information here. Sqrt exists in the global namespace as part of the c libraries. Is it possible that std::sqrt is implemented in terms of ::sqrt on your system? – Richard Hodges May 22 '14 at 23:58
  • [g++ does reject your code](http://coliru.stacked-crooked.com/a/90fb31b221985a15) – Bryan Chen May 23 '14 at 01:05

1 Answers1

2

You just can't call a function sqrt, since that's reserved. Your function is getting called, but your implementation is also including a header file that says that sqrt cannot throw. Change the name of the function to something else and the problem will go away.

You can also see the problem if you change your function to double sqrt(double const& x) {. You'll probably get an error about conflicting overloads.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278