英文:
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;
根据你提到的引用,s1
和 a->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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论