64

avr-gcc でコンパイル中に、次のようなリンカ エラーが発生しました。

undefined reference to `__cxa_pure_virtual'

次のようなドキュメントを見つけました。

この__cxa_pure_virtual関数は、純粋仮想関数が呼び出されたときに呼び出されるエラー ハンドラーです。

純粋仮想関数を持つ C++ アプリケーションを作成している場合は、独自の__cxa_pure_virtualエラー ハンドラー関数を指定する必要があります。例えば:

extern "C" void __cxa_pure_virtual() { while (1); }

この関数を提案どおりに定義するとエラーが修正されますが、知りたいのですが:

  • この機能の目的は何か、
  • なぜ自分で定義する必要があるのか
  • 無限ループとしてコーディングすることが許容されるのはなぜですか?
4

2 に答える 2

45

プログラムのランタイムのどこかで仮想関数ポインタが入力されていない状態でオブジェクトが作成され、対応する関数が呼び出されると、「純粋仮想関数」が呼び出されます。

記述したハンドラは、開発環境に付属するデフォルト ライブラリで定義する必要があります。デフォルトのライブラリを省略すると、このハンドラーが未定義であることがわかります。リンカは宣言を認識しますが、定義は認識しません。その場合は、独自のバージョンを提供する必要があります。

無限ループは「大きな」エラーであるため許容されます。ソフトウェアのユーザーはすぐに気付くでしょう。他の「騒々しい」実装も受け入れられます。

于 2009-05-28T12:02:23.963 に答える
26

1) 関数 __cxa_pure_virtual() の目的は何ですか?

純粋仮想関数は、オブジェクトの構築/破棄中に呼び出すことができます。その場合、__cxa_pure_virtual() が呼び出されてエラーが報告されます。「純粋仮想関数呼び出し」のクラッシュはどこから発生するかを参照してください。

2) なぜ自分で定義する必要があるのでしょうか?

通常、この関数は libstdc++ (Linux など) によって提供されますが、avr-gcc と Arduino ツールチェーンは libstdc++ を提供しません。

Arduino IDE は、「-ffunction-sections -fdata-sections」オプションでコンパイルし、「-Wl,--gc-sections」でリンクして、未使用のシンボルへの参照をいくつか削除するため、一部のプログラムをビルドするときにリンカ エラーを回避することができます。 .

3) __cxa_pure_virtual() を無限ループとしてコーディングできるのはなぜですか?

まあ、これは少なくとも安全です。それは予測可能なことをします。プログラムを中止してエラーを報告する方が便利です。ただし、実行を中断してスタック バックトレースを提供できるデバッガーがない限り、無限ループをデバッグするのは厄介です。

于 2012-02-20T02:38:25.270 に答える