为什么嵌套的数组对象会阻止提供存储?

huangapple go评论73阅读模式
英文:

Why does a nested array object prevent providing storage?

问题

Lifetime下的提供存储部分中,它提到:

> 作为一种特殊情况,如果对象可以在unsigned char或std::byte数组中创建(自C++17以来)(在这种情况下,可以说数组为对象提供存储),前提是
> - 数组的生命周期已经开始且尚未结束
> - 用于新对象的存储完全位于数组内
> - 没有满足这些约束条件的嵌套数组对象。

第三个条件的存在是为什么?

即使有一个嵌套数组(我认为这意味着从外部数组的某个索引开始并以不远处的索引结束的数组,而不是外部数组的项,因为在大多数语言中,“嵌套”这个术语可能会被理解),标准作者或实现为什么不能使外部数组的一部分与嵌套数组不重叠以提供存储?

而且,如果嵌套数组没有任何嵌套在其中的数组,我是否正确理解它可以提供存储?如果是这样,为什么外部数组不能在同一位置提供存储,即提供存储的部分不跨越任何嵌套(也许间接)数组的起始或结束?

此外,即使跨越,标准包含这个要求以避免什么问题?

另外,嵌套数组是否可能不满足第二个条件,即部分重叠?这样的数组是否可以存在?在什么情况下以及在什么条件下一个数组嵌套在另一个数组中?它们是否可以相互嵌套?

英文:

At Lifetime under Providing storage, it says:

> As a special case, objects can be created in arrays of unsigned char or std::byte (since C++17) (in which case it is said that the array provides storage for the object) if
> - the lifetime of the array has begun and not ended
> - the storage for the new object fits entirely within the array
> - there is no array object that satisfies these constraints nested within the array.

Why is the third condition there?

Even if there's a nested array (I believe it means an array which starts at some index of the outer array and ends at an index that's no farther, not an array which is an item of the outer array, as the term nested would probably be understood in most languages), what difficulty does it pose to the standard authors or implementations to enable a segment of the outer array disjoint with the nested array to provide storage?

And, if the nested array doesn't have any array nested in it, do I understand correctly that it can provide storage? If so, why can't the outer array provide storage in the same place, i.e. with the segment providing storage not straddling the start or end of any nested (perhaps indirectly) array?

And, even with straddling, what problems could arise that the standard included this requirement to avoid?

Additionally, can a nested array not satisfy the second condition, i.e. overlap it partially? Can such arrays even exist? In what sense and under ehat conditions is then one nested in another? Can both ever be nested in each other?

答案1

得分: 5

考虑这个示例(忽略对齐):

struct A { std::byte s2[64]; };
std::byte s1[128];
int* i1 = new(s1) int;
A* a = new(s1 + 32) A; // 在某个有效的偏移处创建
int* i2 = new(a->s2) int;

根据你提到的引用,s1a->s2 都满足关于我们创建的整数 i2 的第一和第二条要求。然而,我认为我们都可以一致同意,更精确地确定 a->s2 提供了存储,因为它更紧密地包含了我们的整数(而 s1 提供了 i1 的存储)。第三条要求正是如此,即它确定了为对象提供存储的“最近”数组对象。

嵌套数组不能被认为是“从某个索引开始”的数组,因为它根本不是一个数组。根据C++标准,数组是具有特定类型的对象(其大小信息已经嵌入其中),将起始点或结束点移动不会在该区域自动创建一个数组(从技术上讲,我们可以重新解释该区域,但这很快就会涉及到未定义行为,因此我不认为它与讨论相关)。

英文:

Consider this example (ignoring alignment)

struct A { std::byte s2[64]; };
std::byte s1[128];
int* i1 = new(s1) int;
A* a = new(s1 + 32) A; // Create at some valid offest
int* i2 = new(a->s2) int;

If we go by the quote you brought, both s1 and a->s2 satisfy the first and second bullet with regard to the integer i2 we created. However, I think we can all agree that it would be more precise to identify a->s2 as providing the storage, since it contains our integer more snuggly (while s1 provides storage for i1). The third bullet does exactly that, i.e. it identifies the "nearest" array object that provides the storage for an object.

A nested array cannot be one that "starts at some index", because it won't be an array at all. Arrays under the C++ standard are objects with a specific type (size information is baked into them), and shifting the start or end point won't magically create and array in the region (technically we can reinterpret_cast the region, but that quickly has us courting undefined behavior so I wouldn't consider it pertinent to the discussion).

huangapple
  • 本文由 发表于 2023年7月20日 12:33:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76726688.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定