12

スタンドアロン クラスでオーバーロードされたパブリックで非仮想の非インライン メソッドの順序を変更すると、ABI が壊れますか?

前:

class MyFinalClass
{
public:
    // ...
    void doSomething(char c, int i, int n);
    void doSomething(char c, int i);
    // ...
};

後:

class MyFinalClass
{
public:
    // ...
    void doSomething(char c, int i);
    void doSomething(char c, int i, int n);
    // ...
};

ありがとう!

4

2 に答える 2

11

関数は、クラス内の位置ではなく、名前とシグネチャによってリンクされます。いいえ、あなたはABIを壊していません。

仮想関数は (通常) vtable 内の位置によってリンクされているため、別の問題です。順序を定義するヘッダーに依存するすべてのファイルを一貫して再コンパイルする場合、これは問題になりませんが、クラスがライブラリに存在する場合は問題になる可能性があります。

于 2012-05-10T15:09:14.177 に答える
1

クラスを更新すると、ABI が壊れる原因が 2 つあります。マークが指摘した仮想関数 (関数を仮想としてマークしなかったからではないことを覚えておいてください)。

変数メンバーを使用するため、他のものはインライン関数です。変数メンバーの順序が変更されると、他のソフトウェアでコンパイルされたインラインも壊れます。

Russel Greene (コメントを参照) が指摘したように、変数メンバーの順序によって、割り当てられたオブジェクトのサイズを変更するのに十分なアライメントの違いが生じる可能性があります。それはまたあなたの割り当てを壊します(クライアントのコードが使用すると仮定しますnew

また、メンバーの追加/削除によって ABI が壊れることはないかもしれません (ここにバイトを割り当てたり、そこに単語を割り当てたりすることはできます...) が、それは通常、すぐに問題になります。

于 2012-05-10T15:53:10.210 に答える