在MSVC中强制未对齐的位域打包

时间:2010-11-30 05:12:04

标签: c++ c visual-studio

我有一个位域结构,最多可加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),告诉编译器返回字节而不是int边界。在海湾合作委员会this worked上,产生sizeof(S) == 6

但是,在MSVC05上,即使设置了pack(1),sizeof仍然会达到8!在阅读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一样?

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

如果你使用类型“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;       
};

答案 2 :(得分:0)

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

AFAIK,该标准不允许位域跨越基础类型的字边界。

相关问题