2010-01-23 2 views
3

OSAtomicDecrement (mac 특정 원자 연산)를 사용하려면 4 바이트의 SInt32를 제공해야합니다.멤버가 4 바이트로 정렬되도록하는 방법은 무엇입니까?

이러한 종류의 요리가 가능합니까? 정렬 문제를 해결할 다른 방법이 있습니까?

struct SomeClass { 
    SomeClass() { 
    member_ = &storage_ + ((4 - (&storage_ % 4)) % 4); 
    *member_ = 0; 
    } 

    SInt32 *member_; 

    struct { 
    SInt32 a; 
    SInt32 b; 
    } storage_; 
}; 

답변

5

Mac 사용자는 GCC를 의미합니다. GCC는 변수를 자동으로 정렬 할 수 있습니다 :

__attribute__((__aligned__(4))) int32_t member_; 

GCC와 관련하여 컴파일러 간에는 이식 할 수 없습니다.

+2

이 솔루션의 이점은 이동성이 낮고 추가로 4 바이트의 공간이 사용되기 때문입니다 괜찮습니까?) – gaspard

+0

다른'#ifdef __gcc__'를 추가하고 싶지 않습니다 ... – gaspard

+0

-1 : 포인터의 저장소가 정렬되어 있는지 확인합니다. 예, storage_와 정렬되기 때문에 정렬도되지만 간접적이며 혼란 스럽습니다. 정렬 지정을 권장하려면 변수를 직접 정렬하기 만하면됩니다 (구조체를 삭제하고'__attribute __ ((__ aligned (4)) '멤버를 만듦). SInt32 a_;' –

0

나는 맥 프로그래밍에 대해 아무것도 몰라하지만 난에 작업하는 데 사용 미니 컴퓨터, 포인터는 항상 4 바이트 (워드) 경계에 정렬했다. IIRC, 구조체도 마찬가지입니다. 할당 된 메모리는 항상있었습니다.

4

나는 모든 SInt32가 이미 Mac에서도 정렬되어 있다고 생각합니다.

는 명확히하기 :

struct Foo { 
    SInt32 member; 
}; 

회원은 항상 당신의 구조를 포장하지 않는 한, 제대로 정렬과 문자 후 회원을 배치됩니다.

+0

이것은 PowerPC의 경우이지만 x86에서는 그렇지 않습니다. PPC는 빅 엔디안입니다. 단어는 정렬되어야하지만 리틀 엔디안에서는 보장 할 수 없습니다. – LiraNuna

+2

컴파일러는 x86에서 잘못 정렬 된 액세스를 사용하는 목적으로 코드를 생성하지 않습니다. 심각한 성능 저하를 일으킬 수 있습니다. –

+0

@LiraNuna 사실이 아닙니다. Microsoft Visual C++ 및 GCC는 x86에서 int의 4 바이트 경계를 보장합니다. Visual C++의 경우 MSDN에 문서화되어 있습니다. – mloskot

-1

구조에서 좋은 정렬을 강제로 수행하려면 비트 필드를 사용할 수 있습니다.

struct 
{ 
    Foo _hisFoo; 
    unsigned int dummyAlignment : 0; 
    Foo _myFoo; 
} 
+0

길이가 0 인 비트 필드 패드가 기본 선언 유형의 다음 정렬 경계에 패드됩니다. 이로 인해 다음 멤버가 바이트 경계 (char 비트 필드), 2 바이트 경계 (짧음), 4 바이트 경계 (int 또는 long) 또는 8 바이트 경계 (long long)로 시작합니다. 이전 멤버의 메모리 레이아웃이 해당 경계에서 끝난 경우 패딩이 발생하지 않습니다. – EvilTeach

1

int은 기본적으로 OS X 컴파일러 중 하나에서 4 바이트로 정렬됩니다. 부적절한 포인터 캐스트를 수행하고 구조를 packed 등으로 표시하여 실수로 정렬을 중단하지 않아도됩니다.

0

컴파일러가 TR1 (또는 C++ 0x)을 지원하는 경우 std::aligned_storage 템플릿을 사용할 수 있습니다.

크기가 S이고 정렬이 A 인 공 간을 할당하려면 std::aligned_storage<S, A>::storage 유형의 개체를 할당 할 수 있습니다.

(네임 스페이스는 컴파일러 사이에 차이가있을 수 있습니다. 나는 확장이에 위치해야 네임 스페이스하는 TR1이 지정하지 않은 생각합니다. MSVC에서 네임 스페이스 std::tr1 사용)이 별도로

, 32 비트 정수는 컴파일러에 의해 이미 정렬 된 4 바이트 (적어도 32 비트 정수의 자연 정렬이 4 바이트 인 플랫폼에서)