我使用了打包模板类。根据this,我应该使用#pragma pack包裹它,如以下示例所示:

#include <iostream>

#pragma pack(1)
template<typename X>
struct S {
 int a;
 X b;
};
#pragma pack()

int main()
{
  std::cout << sizeof(S<char>) << "\n";
}

在我的centOS6上使用gcc-4.4.7,程序输出8,这意味着pack(1)无法正常工作。然后我尝试将main()更改为:
int main()
{
  std::cout << sizeof(S<char>) << "\n";

#pragma pack(1)
  std::cout << sizeof(S<char>) << "\n";
#pragma pack()
}

令人惊讶的是,它仍然没有起作用。如果我注释掉main()的第一行,那么它将起作用。所以我的问题是如何在模板类实例上使用pack?无论如何,是否在同一程序中同时使用压缩和解压缩模板类?

更新:如果我使用gcc-5.2.1,则它正确输出5。同样对于以下程序,我得到相反的结果(使用gcc-4.4.7时为5,而使用5.2.1时为8):
template<typename X>
struct S {
 int a;
 X b;
};

int main()
{
#pragma pack(1)
 std::cout << sizeof(S<char>) << "\n";
#pragma pack()
}

为什么gcc-4.4.7和5.2.1的行为不同?哪一个是正确的?无论如何,要获得与不同版本的gcc一致的结果?

最佳答案

这个对我有用

#include <iostream>
#pragma pack(1)
namespace Packed
{
    template<typename X>
    struct S {
     int a;
     X b;
    };

    template struct S<char>;
}
#pragma pack()

namespace NotPacked
{
    template<typename X>
    struct S {
     int a;
     X b;
    };

    template struct S<char>;
}

int main()
{
  std::cout << sizeof(Packed::S<char>) << "\n";
  std::cout << sizeof(NotPacked::S<char>) << "\n";
}

您可以将S的定义放在 header 中(但一次不使用#pragma),并避免代码重复:
#pragma pack(1)
namespace Packed
{
#include "S.h"
}
#pragma pack()

namespace NotPacked
{
#include "S.h"
}

09-10 00:07
查看更多