2010-05-31 1 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; 
    ... 
}; 
편집
종류는 변경되지 않습니다
, 구성원의 순서. 비트 플래그도 사용되지 않습니다. 코드가 공유 라이브러리로 사용되었으므로이 코드에 정적으로 링크되어 있지 않습니다. 저는 리눅스에 있고 컴파일러는 gcc-3.4.3 및 gcc-4.1입니다.

+1

두 경우 모두 인라인으로 제공되므로 생성자와 소멸자를 선언해야합니다. –

+1

@Johannes 예, 선언되었습니다. 설명에서 빠뜨린 것입니다. 그러나 메모를 주셔서 감사합니다. 유용합니다. –

답변

12

A의 크기와 위치의 차이로 인해 다른 이유가있을 수 있습니다. 데이터 멤버간에 바이트를 채 웁니다.

3

C++은 ABi를 정의하지 않습니다. 유일한 답은 "컴파일러에 달려있다"입니다. 대답은 '예'일 것입니다.

+0

그것은 리눅스에서 gcc입니다 –

3

다르게 주문한 비공개 멤버에 액세스하는 함수가있는 두 개의 바이너리로 끝날 수 있기 때문에 둘 이상의 바이너리로 컴파일 된 구현이있는 곳이면 어디든 고장 났을 것입니다. 이것은 가상 함수의 구현을 포함합니다. 가상 함수의 구현은 중복되지 않는 구현을 여러 바이너리로 컴파일 할 수 있기 때문입니다.

가장 좋은 방법은 순수한 가상 함수를 사용하고 '호스트'바이너리에서 인터페이스로 노출시키는 것입니다. 그런 다음 추가 바이너리는 구현이 필요하지 않으므로 항상 '호스트'바이너리로 구현을 호출하므로 불일치가 발생하지 않습니다.

+0

그것은 공유 라이브러리입니다, 나는 그것을 한 곳에서만 컴파일 된 다음 그것을로드하는 바이너리에서 사용했다고 가정합니다. 힌트는 여전히 10 배. –

5

KDE Policies/Binary Compatibility Issues With C++에 따르면 이진 호환성을 손상시키지 않고서는이 작업을 수행 할 수 없습니다. 그러나 면책 조항에 나와있는 것처럼 "할 수 없다"라는 부분에서 제공하는 조언 중 일부는 컴파일러에 따라 다르므로 변경하지 않아도됩니다 (별다른 문제는 아니지만).

+0

KDE Techbase 기사를 인용하면 +1합니다. 웹에서의 ABI 호환성과 관련하여 최고의 조언 모음입니다. – andref

+0

@andref, 이것이 최고라고 의심하지 마십시오. 그냥 가장 잘 알려진 것 같아요 ;-) –