2010-05-31 47 views
9

我有一個私有數據成員數量的類(其中一些是靜態的),可以通過虛擬和非虛擬成員函數訪問。沒有內聯函數,也沒有朋友類。改變類私有數據成員的順序是否改變ABI

class A 
{ 
    int number; 
    string str; 
    static const int static_const_number; 
    bool b; 
public: 
    A(); 
    virtual ~A(); 
public: 
    // got virtual and non-virtual functions, working with these memebers 
    virtual void func1(); 
    void func2(); 

    // no inline functions or friends 
}; 

是否改變私有數據成員打破ABI在這種情況下的順序?

class A 
{ 
    string str; 
    static const int static_const_number; 
    int number; // <-- integer member moved here 
    bool b; 
    ... 
}; 


編輯
的類型沒有變化,只有成員的順序。也沒有使用位標誌。 代碼被用作共享庫,沒有靜態鏈接到這個代碼。 我在Linux上,編譯器是gcc-3.4.3和gcc-4.1

+1

請注意,在你的情況下,你需要聲明一個構造函數和析構函數,因爲它們都以內聯方式提供。 – 2010-05-31 15:09:26

+1

@Johannes是的,他們被宣佈,只是在描述中錯過了他們。不過謝謝你的提示,這很有用。 – 2010-05-31 15:18:41

回答

12

如果沒有其他原因,A的大小可能因位置和數量的不同而不同在數據成員之間填充字節。

3

C++沒有定義ABi。這裏唯一正確的答案是「這取決於你的編譯器」。答案可能是肯定的。

+0

它是linux上的gcc – 2010-05-31 15:33:12

3

它可能會破壞你將實現編譯到多個二進制文件的任何地方,因爲你最終可能會得到兩個函數訪問不同順序的私有成員的二進制文件。這包括虛函數的實現,因爲它們可以將它們未被覆蓋的實現編譯到多個二進制文件中。

最好的方法是使用純粹的虛擬函數並將它們作爲「主機」二進制文件的接口公開。然後額外的二進制文件不需要實現,所以他們總是在'主機'二進制文件中調用實現,這意味着沒有不一致的餘地。

+0

這是一個共享庫,我想它只在一個地方編譯,然後在加載它的二進制文件中使用。仍然是10倍的提示。 – 2010-05-31 15:31:32

5

根據KDE Policies/Binary Compatibility Issues With C++你不能做到這一點不破壞二進制兼容性。然而,正如他們的免責聲明所述,他們在「你不能......」部分給出的一些建議是依賴於編譯器的,所以你可能會逃避這種改變(儘管不太可能)。

+0

+1,用於引用KDE Techbase文章。這當然是關於網絡上ABI兼容性的最佳建議集合。 – andref 2010-06-01 00:47:05

+0

@andref,懷疑它是最好的;只是最知名的,我猜;-) – 2011-01-19 21:33:01