在使用avr-gcc进行编译时,我遇到了链接器错误,如下所示:
undefined reference to `__cxa_pure_virtual'
我发现this document表示:
__cxa_pure_virtual
函数是在调用纯虚函数时调用的错误处理程序。如果您正在编写具有纯虚函数的C ++应用程序,则必须提供自己的
__cxa_pure_virtual
错误处理函数。例如:
extern "C" void __cxa_pure_virtual() { while (1); }
根据建议定义此功能可修复错误,但我想知道:
答案 0 :(得分:38)
如果在程序的运行时中的任何地方创建了一个未填充虚拟函数指针的对象,并且在调用相应的函数时,您将调用“纯虚函数”。
您描述的处理程序应该在开发环境附带的默认库中定义。如果您碰巧省略了默认库,您会发现此处理程序未定义:链接器会看到声明,但没有定义。那时你需要提供自己的版本。
无限循环是可以接受的,因为它是一个“响亮”的错误:软件的用户会立即注意到它。任何其他“响亮”的实现也是可以接受的。
答案 1 :(得分:20)
1)函数__cxa_pure_virtual()的目的是什么?
在对象构建/销毁期间可以调用纯虚函数。如果发生这种情况,将调用__cxa_pure_virtual()来报告错误。见Where do "pure virtual function call" crashes come from?
2)为什么你需要自己定义它?
通常这个函数由libstdc ++提供(例如在Linux上),但avr-gcc和Arduino工具链不提供libstdc ++。
Arduino IDE在构建某些程序时设法避免链接器错误,因为它编译了选项" -ffunction-sections -fdata-sections"和" -Wl, - gc-sections"的链接,删除对未使用符号的一些引用。
3)为什么将__cxa_pure_virtual()编码为无限循环?
嗯,这至少是安全的;它做了一些可预测的事情。中止程序并报告错误会更有用。但是,无限循环会很难调试,除非你有一个可以中断执行并给出堆栈回溯的调试器。