C++运行时,显示异常信息

33

我正在使用Linux上的gcc编译C++代码。有一些异常情况不应该被处理,而应该关闭程序。但是,我想要能够显示异常字符串:

例如:

throw std::runtime_error(" message");不会显示消息,只显示错误类型。我也想显示消息。有没有办法做到这一点?

这是一个库,我真的不想放置catch语句并让库用户决定。然而,现在库用户是Fortran,它不允许处理异常。原则上,我可以在包装器代码中放置处理程序,但如果有其他方法的话,我宁愿不这样做。


2
现在在 g++ 6.2.0,Ubuntu 16.10 上,throw std::runtime_error(" message"); 会显示消息。 - Ciro Santilli OurBigBook.com
1
@AbdelrahmanShoman 完成了! - Ciro Santilli OurBigBook.com
5个回答

42

标准异常有一个虚拟的what()方法,它提供与异常相关联的消息:

int main() {
   try {
       // your stuff
   }
   catch( const std::exception & ex ) {
       cerr << ex.what() << endl;
   }
}

3
如果你的代码旨在被非C++代码使用,那么它应该具有C链接并且不应允许异常逃逸到调用代码中。 - anon
什么是将终端问题传达到主程序的好方法?我需要一些打印错误字符串的工具,而不依赖于Fortran输出。 - Anycorn
1
通过您的C链接接口返回错误代码,并为您的库用户提供一种将这些错误代码转换为字符串的方法。 - Mark B
你的回答中有一个小错别字。应该是ex.what(),你忘记了x。 - scigor
当我抛出std::runtime_error并捕获std::exception时,what()会显示"std::exception"。当我抛出std::runtime_error并捕获std::runtime_error时,what()会显示我放入runtime error的错误消息。 - Samuel Danielson
显示剩余3条评论

8
您可以在主函数中编写以下内容:
try{

}catch(const std::exception &e){
   std::cerr << e.what() << std::endl;
   throw;
}

我加了一些澄清。原则上,如果没有其他办法,我可以采用这种方式。 - Anycorn
请注意,这样做的缺点是会清除您的调用堆栈,而 g++ 通常会在核心文件中保留未捕获异常的调用堆栈。 - Mark B

3
你可以使用 try/catch 块和 throw; 语句来让库用户处理异常。 throw; 语句将控制权转移给同一异常的另一个处理程序。

好的,我想我会在Fortran/C包装器中加入try catch并打印消息,然后从那里抛出异常。然后我会让C++接口自行处理异常。 - Anycorn

3

GCC自6.2.0版本起就会显示此信息。

我曾在g++ 6.2.0、Ubuntu 16.10上测试过它,现在又在g++ 9.3.0 Ubuntu 20.04上进行了测试,两者都显示了这个消息,不确定行为什么时候发生了改变:

#include <stdexcept>

void myfunc() {
    throw std::runtime_error("my message");
}

int main() {
    myfunc();
}

编译并运行:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out

输出包含my message错误信息:

terminate called after throwing an instance of 'std::runtime_error'
  what():  my message

1
我建议为您的库创建一个适配器,以便Fortran调用者可以使用。将您的try/catch放在适配器中。如果您希望从Fortran(或C)调用它但仍允许异常传播到C++调用者,则基本上您的库需要多个入口点。这种方式还具有将C++链接提供给C++调用者的优点。仅具有Fortran接口将大大限制您,因为必须通过引用传递所有内容,您需要考虑char *参数的隐藏参数等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接