2011-07-19 1 views

答えて

3

バイナリ互換性を維持することは何を意味しますか?

オブジェクトのレイアウトは同じになりますが、あなたはバイナリ互換性は基本的に役に立たない、その時点ですべてのコードを、再コンパイルない限り、あなたは一つの定義ルールを破壊されます。再コンパイルをしないと、ODRは破損し、正常に機能している可能性がありますが、機能しない可能性もあります。特に

クラスの仮想メソッドのすべてが、純粋なまたは定義されたいずれかのインラインされている場合、コンパイラは、ヘッダを含む各翻訳単位で仮想テーブルを生成し、弱いシンボルとしてマークかもしれません。リンカはそれらのうちの1つを選択し、他のすべてを破棄します。この状況では、リンカはすべてのvtableがまったく同じであることを確認する必要はなく、ランダムに(または未定義の方法で確定的に)1つを選択し、メソッドが純粋仮想であるvtableを1つ選択することがあります。そのメソッドが基本クラスのオブジェクトに対して呼び出されると、アプリケーションのクラッシュが発生する可能性があります。

+0

私の場合、すべての仮想メソッドが純粋ではない、混合物があります。私は、不確かさで生きるのではなく、とにかくすべてを再構築すると思う。 –

+0

特に私はN個の共有ライブラリを持っていました。私は、最初のlibの基本クラスポインタを介してのみ仮想関数を呼び出しています。他のN-1個のライブラリには、その関数を再実装した派生クラスが含まれています。純粋なものを非純粋なものに変更し、最初のライブラリのみを再コンパイルする予定でした。 –

4

は互換性がありませんがを発行します。 (ただし、virtualから純粋なvirtualまでは問題を引き起こす可能性があります)。

純粋でないvirtualメソッドにはボディが必要です。彼らは実装されていないままにすることはできません。あなたは、単にのように置くことができない、すなわち

class A { 
public: 
    virtual int foo() 
    { 
    return 0; //put some content 
    } 
}; 

virtual int foo(); 

それはあなたがそれを使用しない場合でも、リンカエラーが発生します。

+0

これは実際には安全ではありません。これはODRの違反です(異なる翻訳単位で同じタイプの定義が異なります)。状況によっては問題が発生する可能性があります。 –

+0

@David、例を挙げることはできますか? – iammilind

+0

私は私が答えてくれたと思いますが、私は単純化しようとします。すべての仮想メソッドが純粋仮想クラスまたはクラス定義でインライン定義されている場合は、vtableを作成する変換単位は1つではなく、そのヘッダーを含むすべての変換が存在します。 vtableは弱い記号としてマークされ、リンカーはそれらのどれかをランダムに*選択します。あなたは(純粋ではない、この翻訳単位のための)仮想関数を呼び出し、リンカはその関数が純粋であるのvtable ... –