为了跟踪异常,我尝试重新定义__cxa_throw,但是g++和clang++将生成带有不同函数签名的编译错误。
#include <stdexcept>
extern "C" {
void __cxa_throw(void*, std::type_info*, void(*)(void*)) {}
}
int main() {
throw std::runtime_error("throw");
}上面的代码使用clang++-12编译,没有任何特定的标志,但是g++-10导致了这样的错误:
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*如果我用以下方式更改函数签名:
#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插入代码中:
#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生成此错误:
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。
发布于 2022-08-03 05:30:49
我认为错误信息表明gcc传递void*作为第二个参数,gcc的__cxa_throw也接受void*,而对于clang,类型是std::type_info*。所以我会尝试这样的方法:
#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时都没有错误。
https://stackoverflow.com/questions/73216563
复制相似问题