2010-05-31 6 views
9

Ho una classe con numero di membri di dati privati ​​(alcuni dei quali statici), cui si accede tramite funzioni membro virtuali e non virtuali. Non ci sono funzioni inline e non ci sono classi di amici.Si modifica l'ordine dei membri di dati privati ​​di classe 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 
}; 

Does cambiando l'ordine dei membri di dati privati ​​rompe ABI in questo caso?

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


Modifica
I tipi non sono cambiati, solo l'ordine dei membri. Anche i flag non vengono utilizzati. Il codice viene utilizzato come libreria condivisa, non esiste alcun collegamento statico a questo codice. Sono su Linux e i compilatori sono gcc-3.4.3 e gcc-4.1

+1

Si noti che nel proprio caso, è necessario dichiarare un costruttore e un distruttore, poiché entrambi sono forniti in linea. –

+1

@Johannes Sì, vengono dichiarati, mancano semplicemente nella descrizione. Ma grazie per la nota, è utile. –

risposta

12

Potrebbe, sì, se per nessun altro motivo che la dimensione di A potrebbe essere diversa a causa delle differenze nella posizione e numero di padding byte tra i membri dati.

3

C++ non definisce ABi. L'unica risposta corretta qui è "Dipende dal tuo compilatore". La risposta è probabilmente sì.

+0

è gcc su linux –

3

Probabilmente si romperà in qualsiasi parte in cui le implementazioni siano state compilate in più di un binario, poiché è possibile ritrovarsi con due file binari con funzioni che accedono a membri privati ​​ordinati in modo diverso. Ciò include l'implementazione di funzioni virtuali, perché possono avere le loro implementazioni non sovrascritte compilate anche in più binari.

Il modo migliore è utilizzare pure funzioni virtuali ed esporle come interfacce da un file binario "host". Quindi i binari aggiuntivi non necessitano di un'implementazione, quindi chiamano sempre l'implementazione nel file binario "host", il che significa che non c'è spazio per l'incoerenza.

+0

È una libreria condivisa, suppongo che sia compilata solo in un posto e quindi utilizzata nei binari che la caricano. Ancora 10 volte per il suggerimento. –

5

Secondo KDE Policies/Binary Compatibility Issues With C++ non è possibile farlo senza rompere la compatibilità binaria. Tuttavia, come afferma il loro disclaimer, alcuni dei consigli che danno in "tu non puoi ..." sono dipendenti dal compilatore, quindi potresti farla franca (anche se non è molto probabile).

+0

+1 per aver citato l'articolo di KDE Techbase. È sicuramente la migliore raccolta di consigli sulla compatibilità ABI sul web. – andref

+0

@andref, dubita che sia il migliore; solo il più noto, immagino ;-) –