2013-07-12 4 views
0

#pragma pack 지시문을 _Pragma оperator까지 구현하여 데이터 구조 정렬을위한 매크로를 만들려고합니다. 이 책 의 책에 기술되어 전체 'C : 요컨대 "C 매크로를 이용한 구조체 패킹

#define STR(s) #s 
#define ALIGNMENT(n) _Pragma(STR (pack(n))) 
#define ALIGNLEVEL(l) ALIGNMENT(l) 
int main() 
{ 
    .... 
    if(1) 
    { 
     ALIGNLEVEL(1) 
     printf("%s\n", STR(Byte-aligned: no padding));> 
    } 
    else 
    { 
     ALIGNLEVEL(4) 
     printf("%s\n", STR(four-byte: boundaries)); 

    } 
    typedef struct s 
    { 
     size_t l_num; 
     short h_num; 
     char ch; 
    } s; 

내 구조의 크기 7 바이트 같아야하는 예상 결과 (바이트 배열) 또는 11 바이트 x64 비트 플랫폼 위의 코드는 GCC 4.7.x-Werror 옵션으로 컴파일되며 반환 결과는 8 바이트 (32 비트 OS)입니다.

이 매크로에 어떤 문제가 있습니까?
왜 이런 일이 발생합니까?

+0

매크로의 사용이 적절하지 않은 것으로 의심됩니다. –

답변

2

프로그램은 if 성명 테스트의 평가 결과에 따라 pragma가 영향을 받는다는 가정하에 작성되었습니다. 두 번째 프라그마는 첫 번째 프라그마가 첫 번째 프라그마를 단순히 오버라이드하고 구조체 정렬이 무조건 4로 설정됩니다. 두 번째 ALIGNLEVEL을 주석 처리하면 예상 결과를 얻을 수 있습니다 (ia32에서 gcc 4.8.1 및 x86-64).

본질적으로 컴파일 타임 pragma를 볼 때 컴파일러는 if과 같은 런타임 구성을 무시합니다. if에는 지속적인 테스트가 있지만 쉽게 일정하지 않은 것으로 변경할 수 있으며 컴파일러는 일관된 결과를 제공하지 못합니다. 당신이 런타임 조건에 따라 서로 다른 정렬을 사용해야하는 경우

#if SOME_CONDITION 
    ALIGNLEVEL(1) 
    printf("%s\n", STR(Byte-alligned: no padding));> 
#else 
    ALIGNLEVEL(4) 
    printf("%s\n", STR(four-byte: boundaries)); 
#endif 

, 당신이 두 구조를 정의하고 사이를 전환해야 할 것이다 : 당신이 다른 상황에서 서로 다른 정렬을해야하는 경우에는 전처리를 사용해야합니다 잘 선택된 추상화를 기반으로 하나 또는 다른 것을 사용하는 코드.