考虑到整个C ++ 11标准,任何符合要求的实现是否有可能成功完成下面的第一个断言,但后者失败了?
#include <cassert>
int main(int, char**)
{
const int I = 5, J = 4, K = 3;
const int N = I * J * K;
int arr1d[N] = {0};
int (&arr3d)[I][J][K] = reinterpret_cast<int (&)[I][J][K]>(arr1d);
assert(static_cast<void*>(arr1d) ==
static_cast<void*>(arr3d)); // is this necessary?
arr3d[3][2][1] = 1;
assert(arr1d[3 * (J * K) + 2 * K + 1] == 1); // UB?
}
如果不是,这在技术上是不是UB,并且如果第一个断言被删除,那么答案是否会改变(reinterpret_cast
是否保证在这里保留地址?)?另外,如果重塑是在相反方向(3d到1d)或从6x35阵列到10x21阵列进行的,那该怎么办?
编辑:如果答案是因为reinterpret_cast
这是UB,是否还有一些其他严格遵守的重塑方式(例如,通过static_cast
到/来自中间人void *
)?
答案 0 :(得分:1)
我觉得它会起作用。您分配相同的连续内存。我知道C标准至少保证它是连续的。我不知道C ++ 11标准中的内容。
然而,第一个断言应该始终为真。数组的第一个元素的地址将始终相同。由于分配了相同的内存,因此所有内存地址都是相同的。
因此,我也会说第二个断言将永远成立。至少只要元素的排序总是按行主顺序排列。这也得到了C标准的保证,如果C ++ 11标准说的不同,我会感到惊讶。