为什么使用最大位域序列定义C ++内存?

时间:2017-04-05 07:24:07

标签: c++ memory

最小的存储单位是一个字节,请参阅quotes from standard here

  

C ++内存模型中的基本存储单元是字节。

然后将内存位置定义为可能是相邻的位域:

  

内存位置是标量类型的对象或相邻位域的最大序列,都具有非零宽度。

我想理解这个定义:

  • 如果最小的存储单元是一个字节,为什么我们不将内存位置定义为字节序列?
  • C风格的位域如何与第一句完全吻合?
  • 最大序列的重点是什么?什么是最大的?
  • 如果我们在内存定义中有位域,为什么我们还需要其他东西?例如。 float或int都由位组成,因此'标量类型的对象' -part似乎是冗余的。

2 个答案:

答案 0 :(得分:2)

您可以通过查看以下声明来推断出一些原因:"两个或多个执行线程可以访问单独的内存位置而不会相互干扰。"

即。两个线程无法访问对象的单独字节。并且访问相邻位域的两个线程也可能彼此干扰。

这里的最大序列是因为标准没有准确地指定一个位域序列如何映射到字节,然后可以独立地访问这些字节中的哪一个。在这方面,实施可能会有所不同。然而,位域的最大序列是任何实现可以作为整体分配的最长序列。特别是,最大序列以宽度为0的btfield结束。下一个位域开始一个新序列。

虽然整数和浮点数是由比特组成的,但是#34; bitfield"在C和C ++中专门指的是整数类型的对象成员,其明确指定了以位为单位的宽度。'并非所有由位组成的都是位域。

答案 1 :(得分:2)

让我们分析一下术语:

供参考:

http://en.cppreference.com/w/cpp/language/bit_field http://en.cppreference.com/w/cpp/language/memory_model

字节

如你所说,内存中通常为8位的最小单位,使用内存地址可明确寻址。

位域

使用显式位计数给出的 BITS 序列!

内存位置

每个字节多个类型的地址或(!!!)非零大小的一个有名的位域序列的开头。

您的问题##

让我们将cpp-reference示例与更多的通知一起使用并逐一回答您的问题:

struct S {
    char a;     // memory location #1, 8-bit character, no sequence, see missing :#, scalar-type.
    int b : 5;  // memory location #2, new sequence, new location, integer-type of 5-bits length
    int c : 11, // memory location #2 (continued) integer-type of 11-bits length
          : 0,  // (continued but ending!) IMPORTANT: zero-size-bitfield, sequence ends here!!!
        d : 8;  // memory location #3 integer-type 8-bit, starts a new bit-field sequence, thus, new memory-location
    struct {
        int ee : 8; // memory location #4
    } e;
} obj; // The object 'obj' consists of 4 separate memory locations
  • 如果最小的存储单元是一个字节,为什么我们不将内存位置定义为字节序列?

对于给定的系统类型,即7位整数或4位字符,我们可能希望对内存消耗进行细粒度的位级控制,... 一个字节作为单位的圣杯会否认我们自由

  • C风格的位域如何与第一句完全吻合?

实际上,由于位字段功能起源于C ...... 这里重要的是,即使您使用位域定义结构,仅消耗11位,第一位将在存储器中进行字节对齐,即将具有与8位步长对齐的位置和数据类型最终会消耗至少(!)16位,以保持位域... 存储数据的确切方法至少在C中不是标准化的。

  • 最大序列的重点是什么;什么是最大的?

最大序列的要点是允许单个字段的高效内存对齐,编译器优化,......在这种情况下,最大值表示在大小> gt = 1的序列中声明的所有位域,即没有其他标量类型没有':0'

的位域
  • 如果我们在内存定义中有位域,为什么我们还需要其他东西?例如。 float或int都由位组成,因此'或者是标量类型的对象'部分似乎是冗余的。

不,两者都是由比特组成的,但是:不指定类型的位大小,会使编译器采用默认大小,即int:32位......如果你不需要这么多分辨率的整数值,但是例如只有24位,你写 unsigned int v:24 ,...

当然,写入内容的非位域方式可以用位域表示,例如:

int a,
int b : 32 // should be equal to a

但是(我不知道,这里有船长吗?)

如果系统定义的默认类型为T,则为n位,并且您写的内容如下:

T value : m // m > n

我不知道结果是什么......