【问题标题】:Program executed on Cygwin does not report a thrown exception在 Cygwin 上执行的程序不报告抛出的异常
【发布时间】:2014-08-15 15:31:49
【问题描述】:

当我运行如下所示的简单程序时,我在 Cygwin 和 Ubuntu 操作系统上得到不同的终端输出。

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

在 Cygwin 上,与 Ubuntu 不同,我没有收到任何表明引发异常的消息。这可能是什么原因?我需要为 Cygwin 下载一些东西,以便它按应有的方式处理异常吗?

我正在使用带有 GCC 4.9.0 的 Cygwin 版本 1.7.30 。在 Ubuntu 上,我有版本 13.10 和 GCC 4.8.1 。我怀疑编译器的差异在这种情况下很重要。

【问题讨论】:

  • 遇到同样的问题,谢谢。

标签: c++ ubuntu gcc cygwin outofrangeexception


【解决方案1】:

没有为这种情况定义行为 - 您依靠 C++ 运行时的“善意”来为“您没有捕获异常”发出一些文本,Linux 的 glibc 确实这样做了,而且显然Cygwin 没有。

相反,将您的主代码包装在 try/catch 中以处理 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;
    }
}

按照 Matt McNabb 的建议,一个不错的解决方案是“重命名 main”,然后执行以下操作:

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

请注意,我们返回一个不同于零的值来表示“失败”——我希望至少 Cygwin 已经这样做了。

【讨论】:

  • 有很多不同的选择。异常不必与std::exception 相关,因此最终您需要catch(...) 来确保捕获任何异常。我已经包含了这样的解决方案。
  • 我尝试将std::set_terminate() 设置为我自己的函数,但该函数似乎没有被调用。这不应该在 C++11 中工作吗?
【解决方案2】:

由于您没有捕获异常,因此行为取决于实现/运行时。对于 Linux 和 cygwin,这似乎以不同的方式实现。

您应该自己捕获异常,或者使用this 问题的答案中解释的方法。

【讨论】:

    【解决方案3】:

    调试此类 C++ 错误的一种方法是简单地用 C 重写它,然后将其转换回 C++。 C 更简单,因此将其转换为 C 应该可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 2015-08-23
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 1970-01-01
      • 2012-03-08
      相关资源
      最近更新 更多