在使用 avr-gcc 编译时,我遇到了如下链接器错误:
undefined reference to `__cxa_pure_virtual'
我发现 本文档其中指出:
__cxa_pure_virtual
函数是一个错误处理程序,在调用纯虚函数时调用。
如果您正在编写具有纯虚函数的 C++ 应用程序,则必须提供自己的 __cxa_pure_virtual
错误处理函数。 例如:
extern "C" void __cxa_pure_virtual() { while (1); }
按照建议定义此函数可以修复错误,但我想知道:
- 此函数的目的是什么,
- 我需要自己定义它以及
- 为什么可以将其编码为无限循环?
Whilst compiling with avr-gcc I have encountered linker errors such as the following:
undefined reference to `__cxa_pure_virtual'
I've found this document which states:
The __cxa_pure_virtual
function is an error handler that is invoked when a pure virtual function is called.
If you are writing a C++ application that has pure virtual functions you must supply your own __cxa_pure_virtual
error handler function. For example:
extern "C" void __cxa_pure_virtual() { while (1); }
Defining this function as suggested fixes the errors but I'd like to know:
- what the purpose of this function is,
- why I should need to define it myself and
- why it is acceptable to code it as an infinite loop?
发布评论
评论(3)
如果在程序运行时的任何地方创建了一个对象,但未填充虚函数指针,并且当调用相应的函数时,您将调用“纯虚函数”。
您描述的处理程序应该在您的开发环境附带的默认库中定义。 如果你碰巧省略了默认库,你会发现这个处理程序未定义:链接器看到一个声明,但没有定义。 这时候你就需要提供你自己的版本。
无限循环是可以接受的,因为它是一个“响亮的”错误:软件的用户会立即注意到它。 任何其他“大声”的实现也是可以接受的。
If anywhere in the runtime of your program an object is created with a virtual function pointer not filled in, and when the corresponding function is called, you will be calling a 'pure virtual function'.
The handler you describe should be defined in the default libraries that come with your development environment. If you happen to omit the default libraries, you will find this handler undefined: the linker sees a declaration, but no definition. That's when you need to provide your own version.
The infinite loop is acceptable because it's a 'loud' error: users of your software will immediately notice it. Any other 'loud' implementation is acceptable, too.
1)函数__cxa_pure_virtual()的用途是什么?
纯虚函数可以在对象构造/销毁期间被调用。 如果发生这种情况,则会调用 __cxa_pure_virtual() 来报告错误。 请参阅“纯虚函数调用”崩溃从何而来?< /a>
2) 为什么您可能需要自己定义它?
通常这个函数是由libstdc++提供的(例如在Linux上),但是avr-gcc和Arduino工具链不提供libstdc++。
Arduino IDE 在构建某些程序时设法避免链接器错误,因为它使用选项“-ffunction-sections -fdata-sections”进行编译,并使用“-Wl,--gc-sections”进行链接,这会删除一些对未使用符号的引用。
3) 为什么可以将 __cxa_pure_virtual() 编码为无限循环?
好吧,这至少是安全的; 它做了一些可预测的事情。 中止程序并报告错误会更有用。 但是,无限循环很难调试,除非您有一个可以中断执行并提供堆栈回溯的调试器。
1) What's the purpose of the function __cxa_pure_virtual()?
Pure virtual functions can get called during object construction/destruction. If that happens, __cxa_pure_virtual() gets called to report the error. See Where do "pure virtual function call" crashes come from?
2) Why might you need to define it yourself?
Normally this function is provided by libstdc++ (e.g. on Linux), but avr-gcc and the Arduino toolchain don't provide a libstdc++.
The Arduino IDE manages to avoid the linker error when building some programs because it compiles with the options "-ffunction-sections -fdata-sections" and links with "-Wl,--gc-sections", which drops some references to unused symbols.
3) Why is it acceptable to code __cxa_pure_virtual() as an infinite loop?
Well, this is at least safe; it does something predictable. It would be more useful to abort the program and report the error. An infinite loop would be awkward to debug, though, unless you have a debugger that can interrupt execution and give a stack backtrace.
就我而言,我使用了
clang
,而不是clang++
。clang++
自动链接libstdc++
。 使用gcc
而不是g++
可能会出现类似的问题。In my case I used
clang
, instead ofclang++
.clang++
automatically links thelibstdc++
. A similar problem might be usinggcc
instead ofg++
.