C++内存模型和位字段的最大序列

C++ memory model and maximal sequence of bit fields

本文关键字:字段 内存 模型 C++      更新时间:2023-10-16

下面的例子出现在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"不是一个位置,而是两个。

引用:

  • https://www.stroustrup.com/C++11FAQ.html#memory-model
  • https://en.cppreference.com/w/cpp/language/memory_model

C++标准(6.7.1 intro.memory(使用极其相似的语言,甚至完全相同的示例:

。或具有非零宽度的相邻位字段的最大序列...

[ 示例:声明为

struct {
char a;
int b:5,
c:11,
:0,
d:8;
struct {int ee:8;} e;
}

包含四个单独的内存位置:成员a和位字段de.ee分别是单独的内存位置...

一个区别是它使用"相邻"一词而不是"相邻"一词。

dee是连续的吗?"连续"一词的字面意思是中间没有间隙,这似乎表明它在谈论内存布局(它们之间有填充吗?但这是定义内存布局的标准的一部分,所以如果它根据这个定义事物,它将是循环的!这是一个非常糟糕的词选择,似乎是混淆的根源。

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

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

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++定义而言,abcde是独立的对象。但是abcd被允许在连续的位置序列中共享内存位置(物理字或字节(,因为它们是位字段,尽管e是类类型的对象,并且必须具有唯一的内存位置。非静态成员eee的子对象,这意味着它占据了e的一部分存储空间,所以它保证是一个单独的内存位置。

由于非唯一性,你可以获取e的地址(operator&(,但不能获取dee