我尝试重新定义__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不能编译第一个代码呢?
我的工作环境是wsl 2,使用的是Ubuntu 20.04,g10.3.0,clang12.0.0。
1条答案
按热度按时间f4t66c6m1#
我认为错误消息表明gcc将
void*
作为第二个参数传递,gcc的__cxa_throw
同样接受void*
,而对于clang,类型则是std::type_info*
。因此,我将尝试类似如下的操作:在gcc和clang上编译时不会出现错误:https://gcc.godbolt.org/z/a9qzrvxqT