【问题标题】:Forcing unaligned bitfield packing in MSVC在 MSVC 中强制未对齐的位域打包
【发布时间】:2010-11-30 14:17:44
【问题描述】:

我有一个加起来 48 位的位域结构。在 GCC 上,这正确地导致了 6 字节的结构,但在 MSVC 中,该结构出现了 8 字节。我需要找到一些方法来强制 MSVC 正确打包结构,这既是为了互操作性,也是因为它被用于内存关键型环境。

下面看到的结构由三个 15 位数字、一个 2 位数字和一个 1 位符号组成。 15+15+15+2+1 = 48,所以理论上它应该适合六个字节,对吧?

struct S
{
  unsigned short a:15;
  unsigned short b:15;
  unsigned short c:15;
  unsigned short d:2;
  unsigned short e:1;       
};

但是,在 GCC 和 MSVC 上编译它会导致 sizeof(S) == 8。考虑到这可能与对齐有关,我尝试在结构声明之前使用#pragma pack(1),告诉编译器返回字节边界,而不是整数边界。在 GCC 上,this worked,导致sizeof(S) == 6

然而,在 MSVC05 上,sizeof 仍然是 8,即使设置了pack(1)!阅读this other SO answer 后,我尝试将unsigned short d 替换为unsigned char,并将unsigned short e 替换为bool。结果是sizeof(S) == 7

我发现如果我将 d 拆分为两个一位字段并将它们楔入其他成员之间,结构最终会正确打包。

struct S
{
  unsigned short a:15;
  unsigned short dHi : 1;
  unsigned short b:15;
  unsigned short dLo : 1;
  unsigned short c:15;
  unsigned short e:1;       
};

printf( "%d\n", sizeof(S) ); // "6"

但是像这样拆分 d 很麻烦,并且在我以后必须处理结构时给我带来麻烦。有什么方法可以强制 MSVC 将这个结构打包成 6 个字节,就像 GCC 一样?

【问题讨论】:

    标签: c++ c visual-studio


    【解决方案1】:

    由实现定义字段在结构中的放置方式。如果可以的话,Visual Studio 会将连续的位域放入基础类型中,并浪费剩余的空间。 (C++ Bit Fields in VS)

    【讨论】:

    • 优秀的参考!帮助我解决了我的问题(VC++ 不断将我的 16 位位域变成 4 字节结构。现在我知道为什么了
    【解决方案2】:

    如果你使用类型“unsigned __int64”来声明结构的所有元素,你会得到一个 sizeof(S)=8 的对象,但最后两个字节将不被使用,前六个将包含数据以你想要的格式。

    或者,如果您可以接受某些结构重新排序,这将起作用

    #pragma pack(1)
    struct S3
    {
      unsigned int a:15;
      unsigned int b:15;
      unsigned int d:2;
      unsigned short c:15;
      unsigned short e:1;       
    };
    

    【讨论】:

      【解决方案3】:

      我不这么认为,我认为实际上是 MSVC 的行为是正确的,而 GCC 偏离了标准。

      AFAIK,标准不允许位域跨越底层类型的字边界。

      【讨论】:

      • 自 9.6.1 / "注意:位域在某些机器上跨越分配单元,而不在其他机器上。"
      猜你喜欢
      • 2010-12-02
      • 2012-02-09
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多