기본 콘텐츠로 건너뛰기

6월, 2012의 게시물 표시

Template with #pragma pack bug

일반적으로 C/C++컴파일러는 메모리 퍼포먼스를 위해 구조체 멤버를 새로 순서를 정렬하거나 4바이트 단위로 패딩을 한다. 대부분의 컴파일러는 순서는 바꾸지 않고, 전체크기를 4바이트 단위로 패딩을 하는데, 일반상황에서는 크게 문제를 야기 하지 않는다. 그러나 File이나 Network에서 쓰일 고정길이 레코드 개념으로 쓰다보면 4바이트 단위 패딩은 매우 위험하다. 따라서 컴파일러마다 지시자를 두어 1바이트 단위로 패딩할 수 있게 하였다. GCC는 __attribute__((__packed__)) 지시어를 이용하지만 GCC에만 적용하는 것이고, 일반적으로 VC에서 사용하던 지시자인 #pragma pack을 사용한다. 사용법은 아래와 같다. #pragma pack(push, 1) // ... definition ... #pragma pack(pop) 또는 #pragma pack(1) // ... definition ... #pragma pack() 그런데 이러한 Data structure alignment가 Template과 결합하면 심각한 버그를 만들어낸다. * 2002년에 보고한 내용인데, 2009년에 수정한 GNU GCC팀의 패기에 박수를 보낸다. (응?) #include using namespace std; #pragma pack(1) template<typename _T> struct mystr_t { _T otype; int i; }; #pragma pack() #pragma pack(1) struct inner_t { char c[3]; }; #pragma pack() int main(int argc, char* argv[]) { cout << "sizeof(inner_t): " << sizeof(inner_t) << endl; mystr_t<inner_t> tmp; cout << "sizeof(tmp): " << si