Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;记忆模型与最大位域序列_C++_Bit Fields_Memory Model - Fatal编程技术网

C++ C++;记忆模型与最大位域序列

C++ C++;记忆模型与最大位域序列,c++,bit-fields,memory-model,C++,Bit Fields,Memory Model,下面的示例显示在Stroustrup和CPPreference网站上: struct S { char a; // location #1 int b:5, // location #2 int c:11, int :0, // note: :0 is "special" int d:8; // location #3 s

下面的示例显示在Stroustrup和CPPreference网站上:

struct S {
        char a;         // location #1
        int b:5,        // location #2
        int c:11,
        int :0,         // note: :0 is "special"
        int d:8;        // location #3
        struct {int ee:8;} e;   // location #4
    };
考虑C++标准提供的内存位置定义:

  • 标量类型的对象
  • 长度非零的位字段的最大连续序列
很明显:

  • “a”是一个位置
  • “b-c”是另一个位置
  • “d”是新位置的开始
然而,考虑到上述定义,我不清楚为什么“d-ee”或“d-e”不是一个位置,而是两个位置

参考资料:


首先,存在语法错误,位字段是单独的声明

struct S {
        char a;         // location #1 and storage of subobject a
        int b:5;        // location #2, beginning of new sequence

        int c:11;
        int :0;         // note: :0 is "special", it ends sequence of fields
        int d:8;        // location #3, beginning of new sequence

        struct {        // storage of subobject e, sequence of fields is over
           int ee:8;    // location #4 within e
        } e;   
    };
字段的位置顺序由实现定义

< C++定义>代码> A/COD>、<代码> B<代码>、<代码> C <代码>、<代码> d<代码>和<代码> e <代码>是独立对象。但是
a
b
c
d
允许在连续的位置序列中共享内存位置(物理字或字节),因为它们是位字段,尽管
e
是类类型的对象,并且必须具有唯一的内存位置。非静态成员
ee
e
的子对象,这意味着它占用了
e
的部分存储空间,因此保证它是一个单独的内存位置

由于非唯一性,可以采用<代码> e <代码>的地址(<代码>运算符和<代码> >,但不可使用<代码> d>代码>或<代码> EE >代码>

< p> C++标准()使用极其相似的语言,甚至完全相同的例子:

。。。或者一个最大的相邻位域序列,所有的位域的宽度都不为零

[示例:声明为

struct {
  char a;
  int b:5,
  c:11,
  :0,
  d:8;
  struct {int ee:8;} e;
}
包含四个独立的内存位置:成员
a
和位字段
d
e.ee
都是独立的内存位置

一个区别是,它使用“相邻”一词而不是“连续”一词

d
ee
是连续的吗?单词“连续”的字面意思是中间没有间隙,这似乎表明它在谈论内存布局(它们之间有填充物吗?).但这是定义内存布局的标准的一部分,因此,如果它以此定义事物,那将是循环的!这是一个非常糟糕的词语选择,似乎是混淆的根源


d
ee
相邻吗?这当然是一个更好的词,因为它更明显地与代码有关,而不是与内存布局有关,但我认为您仍然可以对其进行解释,因此在这种情况下,答案要么是肯定的,要么是否定的。但鉴于有一个例子表明它们不是相邻的,我们必须接受“相邻”作为“定义在同一结构中彼此直接相邻的字段”的简写。

从技术上讲,位字段不保证是连续的。它们所拥有的只是拥有非唯一内存位置的权限。即使字段的物理顺序也不是由标准定义的(在大多数实现中,它取决于endianness)。它们占用的内存位置将是连续的,即相邻的,但按位可能会有间隙(0大小的字段是保证跳跃的特殊情况)正如斯威夫特的回答所指出的,C++11常见问题解答中实际上存在一个语法错误!要么在字段之间使用分号,但每次都包含
int
,要么在字段之间使用逗号,但在第一次声明之后不包含
int
。cppreference.com示例和实际标准中不包含此错误。但当然不会这并不影响你的实际问题。我理解这些参数,但是,“e”不是标量,也不是位域。因此严格来说,它不属于内存位置的定义。另一方面,我们可以在内部结构中递归概念,找到位域。然后我们在最后有相邻的位域。
e
不是作为一个,所以它不能与任何前面的位字段位于同一位置,尽管它的内容是一个最大的相邻位字段序列,所有字段的宽度都不为零,特别是单个字段
ee
。因此
ee
是一个单独对象中的单独位置。这个措辞问题是一个非常有趣的问题,实际上可能是混乱的根源。我们在这里处理C++定义(在语言中)和底层内存模型(语言之外,虽然仍然是抽象的,即,与体系结构无关)。