【问题标题】:Catching exception from custom sqrt function fails in C++在 C++ 中从自定义 sqrt 函数捕获异常失败
【发布时间】:2014-05-22 23:29:26
【问题描述】:

我试图演示异常处理,但遇到了一个我无法解决的奇怪问题。问题出现在以下代码中:

#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;
}

代码失败:

 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

但是,如果我将写入的 sqrt 函数的名称更改为“mySqrt”,或者删除标头,则可以正确捕获异常。知道是什么原因造成的吗?

我正在编译通过

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

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

编辑:澄清一下,这似乎不是命名空间问题。代码显然在调用我的 sqrt 函数,如异常消息所示。

编辑 2:此代码仍然无法为我处理异常。

#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;
}

【问题讨论】:

  • 我不明白为什么它是重复的。即使在std 我也不明白为什么会抛出异常而没有被捕获
  • 假设名称没有问题,如果你不抛出异常,函数不会无限递归吗?您的代码会在 Visual Studio 上生成链接器错误,但在那里可以正常工作,如果函数名称发生更改,here
  • 好吧,从技术上讲,链接是正确的:这显然会导致未定义的行为,因此编译器可以随意做任何事情(例如无法正确捕获异常)。
  • 我认为这个问题应该被解锁,因为这里有信息。 Sqrt 作为 c 库的一部分存在于全局命名空间中。 std::sqrt 是否有可能在您的系统上以 ::sqrt 的形式实现?

标签: c++ exception g++4.8


【解决方案1】:

你不能调用函数sqrt,因为它是保留的。您的函数被调用,但您的实现还包括一个标明sqrt 不能抛出的头文件。将函数名称更改为其他名称,问题就会消失。

如果您将函数更改为double sqrt(double const&amp; x) {,您也可以看到问题。您可能会收到有关重载冲突的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    相关资源
    最近更新 更多