这个C++代码是否可移植?(假设多维数组具有连续的内存布局)

Ben*_*enj 18 c++ memory arrays portability multidimensional-array

首先,如果我犯了任何语法错误,对不起我的英语......

我的问题是,当我们有一个二维数组时,如果我是对的,从计算机和C/C++的角度来看,它只是一个长的一维数组,索引只是帮助编译器映射到具体的地址.

这段代码工作在Visual C++,但是我想知道,这个代码是否是便携式符合 标准(C++ 98),不会造成对其他架构和/或操作系统的惊喜:

int arr[][3] = { 1, 5, 3, 7, 5, 2, 7, 8, 9 };
const int ARR_NUM = sizeof(arr) / sizeof(int);

int* ptr = reinterpret_cast<int*>(arr);    // NOT: int(*)[][3] !!!
for (int i = 0; i < ARR_NUM; ++i) {
    cout << ptr[i] << endl;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*Jon 14

Standardese

多维数组的元素按行主顺序顺序存储,因此手动索引是可移植的:

C++ 98,8.3.4/1:

数组类型的对象包含一个类型为T的连续分配的非空N个子对象集.

显然,对于多维数组,这是递归应用的.

但是,这种使用reinterpret_cast不便携.标准说(C++ 98,5.2.10/1)

[...]否则,结果是rvalue,并且对表达式v执行数组到指针,标准转换.

换句话说,传递arr立即触发数组的衰减到指向其第一个元素的指针.然后(C++ 98,5.2.10/3)来了

执行映射是由reinterpret_cast实现定义的.

本节的其余部分列出了许多例外,指定总是定义良好的强制转换.看来它们都不适用于此,结论是技术上它是默认定义的实现.

定论

从理论上讲,这不是便携式的.实际上,只要架构是相同的(例如x86),我当然希望演员可靠地工作.

幸运的是,您不必假设任何类似的东西,因为正如其他人 所提到的,类似int* ptr = arr[0]的东西也是如此,并且保证便携.