Is this C++ code portable? (assuming multidimensional arrays have continuous memory layout)

蓝咒 提交于 2019-12-23 06:50:13

问题


First of all, sorry for my english if i make any grammar mistakes, etc ...

My question is, that when we have a two dimensional array, then if i am right, from the point of the computer and C/C++, it's just a long one dimensional array, the indices are just helping the compiler to map to the concrete address.

This code fragment works in Visual C++, however I would like to know, whether this code is portable and conforms to the standard (C++98), not causing surprises on other architectures and/or operating systems:

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;
}

回答1:


Standardese

The elements of the multidimensional array are stored sequentially in row-major order, so the manual indexing is portable:

C++98, 8.3.4/1:

An object of array type contains a contiguously allocated non-empty set of N sub-objects of type T.

Obviously for a multidimensional array this applies recursively.

However, this use of reinterpret_cast is not portable. The standard says (C++98, 5.2.10/1) that

[...] otherwise, the result is an rvalue and the [...], array-to-pointer, [...] standard conversions are performed on the expression v.

In other words, passing arr immediately triggers a decay of the array to a pointer to its first element. Then (C++98, 5.2.10/3) comes the catch-all

The mapping performed by reinterpret_cast is implementation-defined.

The rest of the section lists a number of exceptions to this, specifying casts that are always well-defined. Seeing as none of them applies here, the conclusion is that technically it's implementation-defined by default.

Final conclusion

Theoretically speaking, this is not portable. Practically, as long as the architectures are the same (e.g. x86) I would certainly expect the cast to work reliably.

Fortunately you don't have to assume anything like that because as others have mentioned, something like int* ptr = arr[0] does the same thing and is guaranteed portable.




回答2:


If you want to be really strict, reinterpret_cast is not terribly well defined in the standard. This will work everywhere, but you could make a pedantic case against it.

Use

int *ptr = arr[0];

to be on the very safe side. The contiguous array layout is guaranteed.




回答3:


If I'm not mistaken reinterpret_cast is not a portable operation.




回答4:


As for the assumption, that multidimensional arrays have continuous memory layout it is standards conformant and portable. It is true ever since the times of C, and C++ does not change this.

However, reinterpret_cast isn't portable, so overall your code isn't guaranteed to work everywhere.



来源:https://stackoverflow.com/questions/10618473/is-this-c-code-portable-assuming-multidimensional-arrays-have-continuous-mem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!