2013-08-19 6 views
11

C++ 03 코드에서 이식 가능하게T과 동일한 크기와 정렬을 가진 unsigned char[sizeof(T)] 버퍼를 구현합니까? 예를 들어C++ 03에서 정렬 된 스택 저장소를 이식 가능하게 구현하는 방법은 무엇입니까?

:

template<class T> 
void test() 
{ 
    unsigned char buffer[sizeof(T)]; // <----- how do I ensure this is aligned? 
    if (some_condition()) 
    { 
     T *const obj = new(buffer) T(); 
     // ... 
     obj->~T(); 
    } 
    else { /* use 'buffer' for something else */ } 
} 

이 경우에도 가능하거나이를 구현하기 위해 컴파일러 확장을 사용하도록 강요?

+0

흥미로운 질문입니다. +1 (destructor를 수동으로 치는 것을 기억함) (비록 내가'const'를 통해 어떻게 그렇게하고 있는지를 놓치고 있지만, 나는'const' 배치를 정말로 닦을 필요가있다). – WhozCraig

+0

@WhozCraig : 감사합니다. pointee는 const가 아니며 포인터 자체는 포인터입니다. :) – Mehrdad

+0

그래, 방금 본거야. = P – WhozCraig

답변

7

그의 Guru Of The Week #28 열에서 Herb Sutter는 (는) 연합을 사용하지만 Boost의 노력보다 덜 강력합니다.

부스트의 aligned_storage은 불만 사항을 해결합니다. 그 구현을 보면 MSCV의 __alignof 또는 GCC의 __alignof__과 다른 템플릿 인 type_with_alignment을 사용하는 것을 볼 수 있습니다. 내 자신의 코드베이스에서

, 내가 한 번 사용 (위의 GOTW 링크에서 파생) : 내가 부스트에 의존하는 단지 것

#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 
# pragma warning(push) 
# pragma warning(disable: 4371) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 
     union AlignedStorage 
     { 
     char  storage[sizeof(T)]; 
     int16  dummy0; 
     int32  dummy1; 
     int64  dummy2; 
     float  dummy3; 
     double  dummy4; 
     long double dummy5; 
     void  (*dummy6)(); 
     struct  dummy7; 
     int   dummy7::*dummy8; 
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 
# pragma warning(push) 
# pragma warning(disable: 4121) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 
     int   (dummy7::*dummy9)(int); 
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 
# pragma warning(pop) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 

     }; // AlignedStorage 
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 
# pragma warning(pop) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 

이 일이 가능성이 더 많은 코너의 경우와 컴파일러 특이성을 다루고 있기 때문에

+0

두 가지 문제 : (1) 이것이 처음 구현되는 방법 **을 묻습니다. 이식성있는 방법이 있나요 아니면 컴파일러 확장이 필요합니까? (2) 두 번째 템플릿 매개 변수 (정렬)로 무엇을 부여합니까? – Mehrdad

+0

편집 # 1 후 - 컴파일러 확장이 필요하다는 말입니까? – Mehrdad

+0

편집 # 2 - 예. 가능한 모든 유형을 결합하여 최대 정렬을 얻을 수 있지만 많은 경우 데이터를 과도하게 정렬하고 공간을 낭비합니다. ** 같은 ** 정렬을 얻으려고 노력하고있어; 더 이상은 아니지만 그 이상. – Mehrdad

2

컴파일러 확장이 __alignof__attribute__((aligned(n)) 인 이유는 정렬 및 결정을 C 및 C++에서 이식 가능하게 구현할 수 없기 때문입니다. 나는. 표준은 그렇게 할 수단이 필요하지 않습니다.

+0

당신이 * 말하려한다면 * 이식 가능하게 구현되지 않았는가, 아니면 실제로 이식 가능하게 구현 될 수 없는지 확실하지 않다. 어느 분이세요? – Mehrdad

+0

c/C++ 표준은 컴파일러에 자유를 남겨 둡니다. 모든 것이 적어도 char로 정렬되어야합니다. C++ 11 정렬은 표준 infact의 일부이며, 정렬은 아마도 대부분의 기존 아키텍처로 이식 가능할 것입니다. – GameDeveloper

+0

@Mehrdad C++ 표준은 그 기능을 필요로하지 않으므로 확장 기능을 필요로하지 않습니다. –