Какова цель __cxa_pure_virtual?
Во время компиляции с avr-gcc я столкнулся с ошибками компоновщика, такими как:
undefined reference to `__cxa_pure_virtual'
Я нашел этот документ, который гласит:
Функция __cxa_pure_virtual
- это обработчик ошибок, который вызывается при вызове чистой виртуальной функции.
Если вы пишете приложение С++ с чистыми виртуальными функциями, вы должны предоставить свою собственную функцию обработки ошибок __cxa_pure_virtual
. Например:
extern "C" void __cxa_pure_virtual() { while (1); }
Определение этой функции, как предложено, исправляет ошибки, но я хотел бы знать:
- Какова цель этой функции,
- почему мне нужно определить его самостоятельно и
- Почему допустимо кодировать его как бесконечный цикл?
Ответы
Ответ 1
Если где-либо во время выполнения вашей программы создается объект с указателем виртуальной функции, который не заполняется, а когда вызывается соответствующая функция, вы вызываете "чистую виртуальную функцию".
Обработчик, который вы описываете, должен быть определен в библиотеках по умолчанию, которые поставляются с вашей средой разработки. Если вы случайно опустите библиотеки по умолчанию, вы найдете этот обработчик undefined: компоновщик видит объявление, но не определение. Это, когда вам нужно предоставить свою собственную версию.
Бесконечный цикл приемлем, потому что это "громкая" ошибка: пользователи вашего программного обеспечения сразу заметят это. Любая другая "громкая" реализация также приемлема.
Ответ 2
1) Какова цель функции __cxa_pure_virtual()?
Чистые виртуальные функции могут быть вызваны во время построения объекта/уничтожения. Если это произойдет, __cxa_pure_virtual() вызывается для сообщения об ошибке. См. Где совершать "чистый вызов виртуальной функции" происходят сбои?
2) Почему вам нужно определить его самостоятельно?
Обычно эта функция предоставляется libstdС++ (например, в Linux), но avr-gcc и инструментальная цепочка Arduino не предоставляют libstdС++.
В Arduino IDE удается избежать ошибки компоновщика при создании некоторых программ, поскольку он компилируется с параметрами "-ffunction-sections -fdata-sections" и связанными с "-Wl, -gc-section", что снижает некоторые ссылки к неиспользуемым символам.
3) Почему допустимо кодировать __cxa_pure_virtual() как бесконечный цикл?
Ну, это по крайней мере безопасно; он делает что-то предсказуемое. Было бы более полезно прервать программу и сообщить об ошибке. Конечно, бесконечный цикл будет неудобным для отладки, если только у вас нет отладчика, который может прервать выполнение и дать стек backtrace.