第一行的声明也是一个定义。 (§3.1(2))
它创建数组对象。 (§1.8(1))
一个对象可以通过多个左值访问
由于别名规则。 (§3.10(10)) 特别是,
右侧可以通过 char 指针合法访问(别名)。
让我们看一下数组定义中的一个句子,然后消除“连续”的歧义。
"一个数组类型的对象包含一个连续分配的非空集
T 类型的 N 个子对象。” [dcl.array] §8.3.4.
消歧
我们从 char 对象的二进制对称关系“连续”开始,这应该是显而易见的。 ('iff' 是 'if and only if' 的缩写,集合和序列是数学的,而不是 C++ 容器)如果可以
链接到更好或更公认的定义、评论。
char 对象的序列 x_1 ... x_N 是连续的,当且仅当
对于所有 i=1...N-1,x_i 和 x_{i+1} 在内存中是连续的。
一组 M char 对象是连续的,当且仅当
M 可以被编号,例如 x_1 ...x_N,使得序列 (x_i)_i 是连续的。
也就是说,当且仅当 M 是一个连续的单射序列的图像。
两组 M_1、M_2 的 char 对象是连续的,如果有的话
在 M_1 中存在 x_1,在 M_2 中存在 x_2,使得 x_1 和 x_2 是连续的。
一个序列 M_1 ... M_N 的 char 对象集是连续的,如果
M_i 和 M_{i+1} 对于所有 i=1...N-1 都是连续的。
一组 char 对象是连续的,当且仅当它是
char 对象集的连续单射序列。
现在要应用哪个版本的“连续”?语言过载解决方案:
1) 'contiguous' 可能指的是'allocation'。作为分配函数调用提供了一个
可用 char 对象的子集,这将调用 set-of-chars 变体。那是,
出现在任何 N 个子对象中的所有 char 对象的集合将意味着是连续的。
2) 'contiguous' 可能指的是 'set'。这将调用 set-of-sets-of-chars 变体,每个子对象都被视为一组 char 对象。
这是什么意思?首先,虽然作者将数组子对象编号为 a[0] ... a[N-1],但他们选择不提及
内存中子对象的顺序:他们使用“set”而不是“sequence”。
他们将分配描述为连续的,但他们没有说
a[j] 和 a[j+1] 在内存中是连续的。此外,他们选择不写下
涉及 (char*) 指针和 sizeof() 的简单公式。虽然看起来他们
故意将连续性与排序关注点分开,
§5.9 (3) 要求对所有类型的数组子对象进行相同的排序。
如果指针指向同一数组的两个不同元素,或其子对象,则指针
下标越高的元素比较越大。
现在组成数组子对象的字节是否符合条件
上述引用意义上的子对象?阅读§1.8(2) 和Complete object or subobject?
答案是:不,至少对于其元素不包含子对象且没有字符数组的数组来说不是这样,例如整数数组。因此,我们可能会发现没有对数组元素施加特定排序的示例。
但现在让我们假设我们的数组子对象只填充了字符。
考虑到“连续”的两种可能解释,这意味着什么?
1) 我们有一组连续的字节与一组有序的子对象一致。
那么 OP 中的声明是无条件正确的。
2) 我们有一个连续的子对象序列,每个子对象可能单独不连续。
这可能以两种方式发生:要么子对象可能有间隙,也就是说,它们
包含两个距离大于 sizeof(subobject)-1 的 char 对象。或者
子对象可能分布在不同的连续字节序列中。
在情况 2) 中,不能保证 OP 中的声明是正确的。
因此,明确“连续”的含义很重要。
最后,这是一个实现示例,其中第 5.9 节没有对数组子对象强加明显的顺序,因为数组子对象本身没有子对象。读者担心这会与其他地方的标准相矛盾,但尚未证明有明确的矛盾。
假设 T 是 int,并且我们有一个特定的符合要求的实现,它的行为与预期一样天真,但有一个例外:
它以相反的内存顺序分配整数数组,
将数组的第一个元素放在对象的高内存地址端:
a[N-1], a[N-2], ... a[0]
而不是
a[0], a[1], ... a[N-1]
此实现满足任何合理的连续性
要求,所以我们不必就单一的解释达成一致
'contiguous' 继续论证。
那么如果 p 指向 a,将 p 映射到 &a[0](调用 [conv.array])将使指针在 a 的高内存端附近跳转。
由于数组算术必须与指针算术兼容,我们也有
int * p= &intVariable;
(char*)(p+1) + sizeof(int) == (char*)p
和
int a[N];
(char*)(void*)&a[n] + n*sizeof(int)==(char*)(void*)&a[0], (0<=n<N)
那么,对于 T=int,不能保证原帖中的说法是正确的。
编辑历史:删除并以修改后的形式重新引入一个可能错误的快捷方式,该快捷方式是由于未应用指针