2010-05-31 4 views
9

Ich habe eine Klasse mit der Anzahl der privaten Datenelemente (einige von ihnen statisch), auf die von virtuellen und nicht virtuellen Member-Funktionen zugegriffen wird. Es gibt keine Inline-Funktionen und keine Freundesklassen.Wird die Reihenfolge der Klasse private Datenelemente bricht 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 
}; 

Ist eine Änderung der Reihenfolge der privaten Datenelemente bricht ABI in diesem Fall?

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


bearbeiten
Die Typen werden nicht verändert, nur die Reihenfolge der Mitglieder. Es werden auch keine Bit-Flags verwendet. Der Code wird als gemeinsam genutzte Bibliothek verwendet. Es gibt keine statische Verknüpfung zu diesem Code. Ich bin auf Linux und die Compiler sind gcc-3.4.3 und gcc-4.1

+1

Beachten Sie, dass Sie in Ihrem Fall einen Konstruktor und einen Destruktor deklarieren müssen, da beide inline bereitgestellt werden. –

+1

@Johannes Ja, sie sind deklariert, nur knapp in der Beschreibung. Aber danke für die Notiz, es ist nützlich. –

Antwort

12

Es könnte, ja, wenn aus keinem anderen Grund, dass die Größe von A aufgrund von Unterschieden in der Lage und Anzahl abweichen könnte von Füllbytes zwischen den Datenelementen.

3

C++ definiert keine ABi. Die einzige richtige Antwort hier ist "Es hängt von Ihrem Compiler ab". Die Antwort ist wahrscheinlich ja.

+0

es ist GCC auf Linux –

3

Es wird wahrscheinlich irgendwo brechen Sie haben Implementierungen in mehr als einer Binärdatei kompiliert, weil Sie am Ende mit zwei Binärdateien mit Funktionen, die auf unterschiedlich geordnete private Mitglieder zugreifen können. Dies schließt Implementierungen von virtuellen Funktionen ein, da sie ihre nicht-überschreibenden Implementierungen auch in mehrere Binärdateien kompilieren lassen können.

Der beste Weg ist, pure virtuelle Funktionen zu verwenden und diese als Schnittstellen von einem "Host" -Binär zu exponieren. Dann benötigen zusätzliche Binärdateien keine Implementierung, daher rufen sie die Implementierung immer in der Binärdatei 'host' auf, was keinen Platz für Inkonsistenzen bietet.

+0

Es ist eine gemeinsame Bibliothek, ich nehme an, es ist nur an einem Ort kompiliert und dann in Binärdateien verwendet, die es laden. Immer noch 10x für den Hinweis. –

5

Nach KDE Policies/Binary Compatibility Issues With C++ können Sie es nicht tun, ohne Binärkompatibilität zu brechen. Wie in ihrem Haftungsausschluss angegeben, sind einige der Ratschläge, die sie im "you can not ..." -Teil geben, vom Compiler abhängig, so dass Sie mit dieser Änderung davonkommen können (obwohl dies nicht sehr wahrscheinlich ist).

+0

+1 für diesen KDE Techbase Artikel zitiert. Es ist sicherlich die beste Sammlung von Ratschlägen bezüglich ABI-Kompatibilität im Internet. – andref

+0

@andref, bezweifle, dass es das Beste ist; nur die bekannteste, denke ich ;-) –

Verwandte Themen