首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么重新定义__cxa_throw会导致编译错误?

为什么重新定义__cxa_throw会导致编译错误?
EN

Stack Overflow用户
提问于 2022-08-03 05:17:13
回答 1查看 120关注 0票数 2

为了跟踪异常,我尝试重新定义__cxa_throw,但是g++和clang++将生成带有不同函数签名的编译错误。

代码语言:javascript
复制
#include <stdexcept>
extern "C" {
  void __cxa_throw(void*, std::type_info*, void(*)(void*)) {}
}
int main() {
  throw std::runtime_error("throw");
}

上面的代码使用clang++-12编译,没有任何特定的标志,但是g++-10导致了这样的错误:

代码语言:javascript
复制
main.cpp: In function ‘int main()’:
main.cpp:6:35: error: invalid conversion from ‘void*’ to ‘std::type_info*’ [-fpermissive]
    6 | int main() { throw std::runtime_error("throw"); }
      |                                              ^
      |                                              |
      |                                              void*

如果我用以下方式更改函数签名:

代码语言:javascript
复制
#include <stdexcept>
extern "C" {
  void __cxa_throw(void*, void*, void(*)(void*)) {}
}
int main() {
  throw std::runtime_error("throw");
}

std::type_info*现在变成void*,g++-10和clang++-12编译.

但是,如果我将cxxabi.h插入代码中:

代码语言:javascript
复制
#include <stdexcept>
#include <cxxabi.h>
extern "C" {
  void __cxa_throw(void*, void*, void(*)(void*)) {}
}
int main() {
  throw std::runtime_error("throw");
}

g++-10仍然编译,clang++-12生成此错误:

代码语言:javascript
复制
main.cpp:4:8: error: conflicting types for '__cxa_throw'
  void __cxa_throw(void*, void*, void (*) (void *)) {}
       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cxxabi.h:616:3: note: previous declaration is here
  __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *))
  ^
1 error generated.

这意味着cxxabi.h中第二个参数的类型是std::type_info*,但是为什么g++-10不能编译第一段代码呢?

我的环境是wsl2和Ubuntu20.04,g++10.3.0,clang++12.0.0。

EN

回答 1

Stack Overflow用户

发布于 2022-08-03 05:30:49

我认为错误信息表明gcc传递void*作为第二个参数,gcc的__cxa_throw也接受void*,而对于clang,类型是std::type_info*。所以我会尝试这样的方法:

代码语言:javascript
复制
#include <stdexcept>
#include <cxxabi.h>
#include <stdlib.h>

extern "C" {

#if !__clang__
  void __cxa_throw(void*, void*, void(*)(void*)) { abort(); }
  //abort to avoid warnings about noreturn functions
#else
  void __cxa_throw(void*, std::type_info*, void(*)(void*)) { abort(); }
  

#endif

}
int main() {
  throw std::runtime_error("throw");
}

它编译gcc和clang:https://gcc.godbolt.org/z/a9qzrvxqT时都没有错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73216563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档