2012-01-17 126 views
5

数据长度我碰到这个语法,我没有C++指定与数据类型声明

struct A { 
    int x:24; 
}; 

见过来到什么是X:24是什么意思?在C++中,你可以指定一个编译器,一个变量应该只占用24位,而不是32位的int类型? 如果是,哪些24位将被占用?最左边还是最右边?

+0

X会做出很好奇INT,如果它是一个标准的系统INT的MSB部分。 – 2012-01-17 19:03:21

回答

6

这是bit fields feature。它早在C天就已经可用了。微软有a nice write-up on this feature,完整的漂亮的图片显示特定于编译器的布局(他们说图片是特定于MS的)。

+2

unsigned:0;是我以前没有意识到的有趣功能。 – 2012-01-17 19:06:18

+0

但请注意,漂亮的图片只能描述微软如何选择实现它;一般来说,布局是实现定义的。 – 2012-01-17 19:07:58

+0

@MikeSeymour你绝对正确:这一点是我编辑的主题。 – dasblinkenlight 2012-01-17 19:09:03

4

这正是你认为它是,称为位字段x有24位可用。

// standard 32bit integer: 
0000 0000 0000 0000 0000 0000 0000 0000 
// x (24 bit): 
0000 0000 | 0000 0000 0000 0000 0000 0000 
//  ^-- cut off here 
// other 8 bit available for other uses, for example: 

struct A{ 
    int x : 24; 
    int y : 8; 
}; // sizeof(A) == sizeof(int) (most likely on 32bit architecture) 

请注意,该结构仍然是32位(或4字节)大,因为你不能只切断那些多余的位。因此,当你有很紧的空间需求,需要尽可能多的信息可以装入较小的空间尽可能位字段是最有用。

+0

如果你愿意用猜测来详细说明,在这些情况下,编译器是否实现了mask + bitshift? (移位) – 2012-01-17 19:07:51

+1

@CaptainGiraffe:最有可能的。在硬件层面上,您不能以任何其他方式撕开单词IIRC。不过有趣的是,任何一个位字段的溢出都不会影响任何其他位字段(如果'x'会溢出,'y'不会改变)(除了这种情况,溢出将是未定义的行为,因为'x'被签名...)。 – Xeo 2012-01-17 19:11:19

+0

在上面的例子中,在int x:24之后是否会有一个填充值,以保持int对齐到32位,或者将来自变量x的余下8位用于填充变量Y的值? – Jimm 2012-01-17 19:29:35

4

如果是,这24位被占用?最左边还是最右边?

它是在C++标准指定(§9.6/ 1:位字段被分配从右到左在某些机器上,左到右他人)。

通常它依赖于平台的字节序。在一个小型平台,将被填上:

[ bits 0~7 ] [ bits 8~15 ] [ bits 16~23 ] [ bits 24~31 ] 
----------------------------------------- -------------- 
        x       (padding) 

和大端平台

[ bits 0~7 ] [ bits 8~15 ] [ bits 16~23 ] [ bits 24~31 ] 
------------ ------------------------------------------- 
    (padding)      x 
+0

编译器如何将结构与位域进行对齐?它是否会在结构的末尾填充足够的位,以便在32位平台上对齐32位?如果一个结构有一个像位int x:8和另一个常规字段int y;在这个例子中,填充将应用于哪里? – Jimm 2012-01-17 19:38:34

+0

@Jimm:您可以看到[@dasblinkenlight](http://docs.microsoft.com/zh-cn/library/default.aspx)提供的[链接](http://msdn.microsoft.com/zh-cn/library/ewwyfdbe%28v=vs.100%29.aspx) /stackoverflow.com/a/8900155/224671) – kennytm 2012-01-17 19:45:02

1

位的排序是CPU依赖逆转。也许你可以写一些简单的东西到这个字段,然后看看调试器中的内存字。

+0

我会想象编译器会在这里做繁重的工作,而不是CPU。 – 2012-01-17 19:12:23